Coverage Report

Created: 2022-08-24 06:55

/src/solidity/libsolutil/Common.h
Line
Count
Source
1
/*
2
  This file is part of solidity.
3
4
  solidity is free software: you can redistribute it and/or modify
5
  it under the terms of the GNU General Public License as published by
6
  the Free Software Foundation, either version 3 of the License, or
7
  (at your option) any later version.
8
9
  solidity is distributed in the hope that it will be useful,
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
  GNU General Public License for more details.
13
14
  You should have received a copy of the GNU General Public License
15
  along with solidity.  If not, see <http://www.gnu.org/licenses/>.
16
*/
17
// SPDX-License-Identifier: GPL-3.0
18
/** @file Common.h
19
 * @author Gav Wood <i@gavwood.com>
20
 * @date 2014
21
 *
22
 * Very common stuff (i.e. that every other header needs except vector_ref.h).
23
 */
24
25
#pragma once
26
27
// way too many unsigned to size_t warnings in 32 bit build
28
#ifdef _M_IX86
29
#pragma warning(disable:4244)
30
#endif
31
32
#if _MSC_VER && _MSC_VER < 1900
33
#define _ALLOW_KEYWORD_MACROS
34
#define noexcept throw()
35
#endif
36
37
#ifdef __INTEL_COMPILER
38
#pragma warning(disable:3682) //call through incomplete class
39
#endif
40
41
#include <libsolutil/vector_ref.h>
42
43
#include <boost/version.hpp>
44
#if (BOOST_VERSION < 106500)
45
#error "Unsupported Boost version. At least 1.65 required."
46
#endif
47
48
#include <map>
49
#include <utility>
50
#include <vector>
51
#include <functional>
52
#include <string>
53
54
namespace solidity
55
{
56
57
// Binary data types.
58
using bytes = std::vector<uint8_t>;
59
using bytesRef = util::vector_ref<uint8_t>;
60
using bytesConstRef = util::vector_ref<uint8_t const>;
61
62
// Map types.
63
using StringMap = std::map<std::string, std::string>;
64
65
// String types.
66
using strings = std::vector<std::string>;
67
68
/// RAII utility class whose destructor calls a given function.
69
class ScopeGuard
70
{
71
public:
72
15.8M
  explicit ScopeGuard(std::function<void(void)> _f): m_f(std::move(_f)) {}
73
15.8M
  ~ScopeGuard() { m_f(); }
74
75
private:
76
  std::function<void(void)> m_f;
77
};
78
79
/// RAII utility class that sets the value of a variable for the current scope and restores it to its old value
80
/// during its destructor.
81
template<typename V>
82
class ScopedSaveAndRestore
83
{
84
public:
85
  explicit ScopedSaveAndRestore(V& _variable, V&& _value): m_variable(_variable), m_oldValue(std::move(_value))
86
85.1k
  {
87
85.1k
    std::swap(m_variable, m_oldValue);
88
85.1k
  }
solidity::ScopedSaveAndRestore<solidity::frontend::FunctionDefinition const*>::ScopedSaveAndRestore(solidity::frontend::FunctionDefinition const*&, solidity::frontend::FunctionDefinition const*&&)
Line
Count
Source
86
42.5k
  {
87
42.5k
    std::swap(m_variable, m_oldValue);
88
42.5k
  }
solidity::ScopedSaveAndRestore<solidity::frontend::ContractDefinition const*>::ScopedSaveAndRestore(solidity::frontend::ContractDefinition const*&, solidity::frontend::ContractDefinition const*&&)
Line
Count
Source
86
42.5k
  {
87
42.5k
    std::swap(m_variable, m_oldValue);
88
42.5k
  }
Unexecuted instantiation: solidity::ScopedSaveAndRestore<solidity::yul::CFG::FunctionInfo const*>::ScopedSaveAndRestore(solidity::yul::CFG::FunctionInfo const*&, solidity::yul::CFG::FunctionInfo const*&&)
Unexecuted instantiation: solidity::ScopedSaveAndRestore<solidity::yul::Scope*>::ScopedSaveAndRestore(solidity::yul::Scope*&, solidity::yul::Scope*&&)
Unexecuted instantiation: solidity::ScopedSaveAndRestore<std::__1::optional<solidity::yul::ControlFlowGraphBuilder::ForLoopInfo> >::ScopedSaveAndRestore(std::__1::optional<solidity::yul::ControlFlowGraphBuilder::ForLoopInfo>&, std::__1::optional<solidity::yul::ControlFlowGraphBuilder::ForLoopInfo>&&)
Unexecuted instantiation: solidity::ScopedSaveAndRestore<std::__1::set<solidity::yul::YulString, std::__1::less<solidity::yul::YulString>, std::__1::allocator<solidity::yul::YulString> > >::ScopedSaveAndRestore(std::__1::set<solidity::yul::YulString, std::__1::less<solidity::yul::YulString>, std::__1::allocator<solidity::yul::YulString> >&, std::__1::set<solidity::yul::YulString, std::__1::less<solidity::yul::YulString>, std::__1::allocator<solidity::yul::YulString> >&&)
Unexecuted instantiation: solidity::ScopedSaveAndRestore<solidity::yul::DataFlowAnalyzer::State>::ScopedSaveAndRestore(solidity::yul::DataFlowAnalyzer::State&, solidity::yul::DataFlowAnalyzer::State&&)
Unexecuted instantiation: solidity::ScopedSaveAndRestore<unsigned long>::ScopedSaveAndRestore(unsigned long&, unsigned long&&)
Unexecuted instantiation: solidity::ScopedSaveAndRestore<std::__1::map<solidity::yul::YulString, std::__1::map<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*, solidity::yul::UnusedStoreBase::State, std::__1::less<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*>, std::__1::allocator<std::__1::pair<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const* const, solidity::yul::UnusedStoreBase::State> > >, std::__1::less<solidity::yul::YulString>, std::__1::allocator<std::__1::pair<solidity::yul::YulString const, std::__1::map<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*, solidity::yul::UnusedStoreBase::State, std::__1::less<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*>, std::__1::allocator<std::__1::pair<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const* const, solidity::yul::UnusedStoreBase::State> > > > > > >::ScopedSaveAndRestore(std::__1::map<solidity::yul::YulString, std::__1::map<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*, solidity::yul::UnusedStoreBase::State, std::__1::less<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*>, std::__1::allocator<std::__1::pair<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const* const, solidity::yul::UnusedStoreBase::State> > >, std::__1::less<solidity::yul::YulString>, std::__1::allocator<std::__1::pair<solidity::yul::YulString const, std::__1::map<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*, solidity::yul::UnusedStoreBase::State, std::__1::less<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*>, std::__1::allocator<std::__1::pair<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const* const, solidity::yul::UnusedStoreBase::State> > > > > >&, std::__1::map<solidity::yul::YulString, std::__1::map<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*, solidity::yul::UnusedStoreBase::State, std::__1::less<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*>, std::__1::allocator<std::__1::pair<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const* const, solidity::yul::UnusedStoreBase::State> > >, std::__1::less<solidity::yul::YulString>, std::__1::allocator<std::__1::pair<solidity::yul::YulString const, std::__1::map<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*, solidity::yul::UnusedStoreBase::State, std::__1::less<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*>, std::__1::allocator<std::__1::pair<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const* const, solidity::yul::UnusedStoreBase::State> > > > > >&&)
Unexecuted instantiation: solidity::ScopedSaveAndRestore<solidity::yul::UnusedStoreBase::ForLoopInfo>::ScopedSaveAndRestore(solidity::yul::UnusedStoreBase::ForLoopInfo&, solidity::yul::UnusedStoreBase::ForLoopInfo&&)
Unexecuted instantiation: solidity::ScopedSaveAndRestore<std::__1::map<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*, solidity::yul::UnusedStoreEliminator::Operation, std::__1::less<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*>, std::__1::allocator<std::__1::pair<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const* const, solidity::yul::UnusedStoreEliminator::Operation> > > >::ScopedSaveAndRestore(std::__1::map<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*, solidity::yul::UnusedStoreEliminator::Operation, std::__1::less<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*>, std::__1::allocator<std::__1::pair<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const* const, solidity::yul::UnusedStoreEliminator::Operation> > >&, std::__1::map<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*, solidity::yul::UnusedStoreEliminator::Operation, std::__1::less<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*>, std::__1::allocator<std::__1::pair<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const* const, solidity::yul::UnusedStoreEliminator::Operation> > >&&)
Unexecuted instantiation: solidity::ScopedSaveAndRestore<solidity::yul::ControlFlowNode*>::ScopedSaveAndRestore(solidity::yul::ControlFlowNode*&, solidity::yul::ControlFlowNode*&&)
Unexecuted instantiation: solidity::ScopedSaveAndRestore<solidity::yul::ControlFlowNode const*>::ScopedSaveAndRestore(solidity::yul::ControlFlowNode const*&, solidity::yul::ControlFlowNode const*&&)
89
  ScopedSaveAndRestore(ScopedSaveAndRestore const&) = delete;
90
85.1k
  ~ScopedSaveAndRestore() { std::swap(m_variable, m_oldValue); }
solidity::ScopedSaveAndRestore<solidity::frontend::FunctionDefinition const*>::~ScopedSaveAndRestore()
Line
Count
Source
90
42.5k
  ~ScopedSaveAndRestore() { std::swap(m_variable, m_oldValue); }
solidity::ScopedSaveAndRestore<solidity::frontend::ContractDefinition const*>::~ScopedSaveAndRestore()
Line
Count
Source
90
42.5k
  ~ScopedSaveAndRestore() { std::swap(m_variable, m_oldValue); }
Unexecuted instantiation: solidity::ScopedSaveAndRestore<solidity::yul::CFG::FunctionInfo const*>::~ScopedSaveAndRestore()
Unexecuted instantiation: solidity::ScopedSaveAndRestore<solidity::yul::Scope*>::~ScopedSaveAndRestore()
Unexecuted instantiation: solidity::ScopedSaveAndRestore<std::__1::optional<solidity::yul::ControlFlowGraphBuilder::ForLoopInfo> >::~ScopedSaveAndRestore()
Unexecuted instantiation: solidity::ScopedSaveAndRestore<std::__1::set<solidity::yul::YulString, std::__1::less<solidity::yul::YulString>, std::__1::allocator<solidity::yul::YulString> > >::~ScopedSaveAndRestore()
Unexecuted instantiation: solidity::ScopedSaveAndRestore<solidity::yul::DataFlowAnalyzer::State>::~ScopedSaveAndRestore()
Unexecuted instantiation: solidity::ScopedSaveAndRestore<unsigned long>::~ScopedSaveAndRestore()
Unexecuted instantiation: solidity::ScopedSaveAndRestore<std::__1::map<solidity::yul::YulString, std::__1::map<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*, solidity::yul::UnusedStoreBase::State, std::__1::less<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*>, std::__1::allocator<std::__1::pair<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const* const, solidity::yul::UnusedStoreBase::State> > >, std::__1::less<solidity::yul::YulString>, std::__1::allocator<std::__1::pair<solidity::yul::YulString const, std::__1::map<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*, solidity::yul::UnusedStoreBase::State, std::__1::less<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*>, std::__1::allocator<std::__1::pair<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const* const, solidity::yul::UnusedStoreBase::State> > > > > > >::~ScopedSaveAndRestore()
Unexecuted instantiation: solidity::ScopedSaveAndRestore<solidity::yul::UnusedStoreBase::ForLoopInfo>::~ScopedSaveAndRestore()
Unexecuted instantiation: solidity::ScopedSaveAndRestore<std::__1::map<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*, solidity::yul::UnusedStoreEliminator::Operation, std::__1::less<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const*>, std::__1::allocator<std::__1::pair<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> const* const, solidity::yul::UnusedStoreEliminator::Operation> > > >::~ScopedSaveAndRestore()
Unexecuted instantiation: solidity::ScopedSaveAndRestore<solidity::yul::ControlFlowNode*>::~ScopedSaveAndRestore()
Unexecuted instantiation: solidity::ScopedSaveAndRestore<solidity::yul::ControlFlowNode const*>::~ScopedSaveAndRestore()
91
  ScopedSaveAndRestore& operator=(ScopedSaveAndRestore const&) = delete;
92
93
private:
94
  V& m_variable;
95
  V m_oldValue;
96
};
97
98
template<typename V, typename... Args>
99
ScopedSaveAndRestore(V, Args...) -> ScopedSaveAndRestore<V>;
100
101
}