Coverage Report

Created: 2025-09-04 07:34

/src/solidity/libsolutil/SetOnce.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
18
#pragma once
19
20
#include <libsolutil/Assertions.h>
21
#include <libsolutil/Exceptions.h>
22
23
#include <memory>
24
#include <optional>
25
#include <utility>
26
27
namespace solidity::util
28
{
29
30
DEV_SIMPLE_EXCEPTION(BadSetOnceReassignment);
31
DEV_SIMPLE_EXCEPTION(BadSetOnceAccess);
32
33
/// A class that stores a value that can only be set once
34
/// \tparam T the type of the stored value
35
template<typename T>
36
class SetOnce
37
{
38
public:
39
  /// Initializes the class to have no stored value.
40
3.47M
  SetOnce() = default;
solidity::util::SetOnce<solidity::frontend::VirtualLookup>::SetOnce()
Line
Count
Source
40
355k
  SetOnce() = default;
solidity::util::SetOnce<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::SetOnce()
Line
Count
Source
40
70.9k
  SetOnce() = default;
solidity::util::SetOnce<std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::vector<solidity::frontend::Declaration const*, std::__1::allocator<solidity::frontend::Declaration const*> >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, std::__1::vector<solidity::frontend::Declaration const*, std::__1::allocator<solidity::frontend::Declaration const*> > > > > >::SetOnce()
Line
Count
Source
40
30.0k
  SetOnce() = default;
solidity::util::SetOnce<bool>::SetOnce()
Line
Count
Source
40
2.78M
  SetOnce() = default;
solidity::util::SetOnce<std::__1::shared_ptr<solidity::frontend::CallGraph const> >::SetOnce()
Line
Count
Source
40
55.9k
  SetOnce() = default;
Unexecuted instantiation: solidity::util::SetOnce<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0> >::SetOnce()
solidity::util::SetOnce<solidity::frontend::FunctionDefinition const*>::SetOnce()
Line
Count
Source
40
140k
  SetOnce() = default;
solidity::util::SetOnce<solidity::frontend::FunctionCallKind>::SetOnce()
Line
Count
Source
40
38.1k
  SetOnce() = default;
41
42
  // Not copiable
43
  SetOnce(SetOnce const&) = delete;
44
  SetOnce(SetOnce&&) = delete;
45
46
  // Not movable
47
  SetOnce& operator=(SetOnce const&) = delete;
48
  SetOnce& operator=(SetOnce&&) = delete;
49
50
  /// @brief Sets the stored value to \p _newValue
51
  /// @throws BadSetOnceReassignment when the stored value has already been set
52
  /// @return `*this`
53
  constexpr SetOnce& operator=(T _newValue) &
54
3.15M
  {
55
3.15M
    assertThrow(
56
3.15M
      !m_value.has_value(),
57
3.15M
      BadSetOnceReassignment,
58
3.15M
      "Attempt to reassign to a SetOnce that already has a value."
59
3.15M
    );
60
61
3.15M
    m_value.emplace(std::move(_newValue));
62
3.15M
    return *this;
63
3.15M
  }
solidity::util::SetOnce<std::__1::shared_ptr<solidity::frontend::CallGraph const> >::operator=(std::__1::shared_ptr<solidity::frontend::CallGraph const>) &
Line
Count
Source
54
35.8k
  {
55
35.8k
    assertThrow(
56
35.8k
      !m_value.has_value(),
57
35.8k
      BadSetOnceReassignment,
58
35.8k
      "Attempt to reassign to a SetOnce that already has a value."
59
35.8k
    );
60
61
35.8k
    m_value.emplace(std::move(_newValue));
62
35.8k
    return *this;
63
35.8k
  }
solidity::util::SetOnce<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::operator=(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) &
Line
Count
Source
54
70.9k
  {
55
70.9k
    assertThrow(
56
70.9k
      !m_value.has_value(),
57
70.9k
      BadSetOnceReassignment,
58
70.9k
      "Attempt to reassign to a SetOnce that already has a value."
59
70.9k
    );
60
61
70.9k
    m_value.emplace(std::move(_newValue));
62
70.9k
    return *this;
63
70.9k
  }
solidity::util::SetOnce<std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::vector<solidity::frontend::Declaration const*, std::__1::allocator<solidity::frontend::Declaration const*> >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, std::__1::vector<solidity::frontend::Declaration const*, std::__1::allocator<solidity::frontend::Declaration const*> > > > > >::operator=(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::vector<solidity::frontend::Declaration const*, std::__1::allocator<solidity::frontend::Declaration const*> >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, std::__1::vector<solidity::frontend::Declaration const*, std::__1::allocator<solidity::frontend::Declaration const*> > > > >) &
Line
Count
Source
54
28.7k
  {
55
28.7k
    assertThrow(
56
28.7k
      !m_value.has_value(),
57
28.7k
      BadSetOnceReassignment,
58
28.7k
      "Attempt to reassign to a SetOnce that already has a value."
59
28.7k
    );
60
61
28.7k
    m_value.emplace(std::move(_newValue));
62
28.7k
    return *this;
63
28.7k
  }
solidity::util::SetOnce<bool>::operator=(bool) &
Line
Count
Source
54
2.54M
  {
55
2.54M
    assertThrow(
56
2.54M
      !m_value.has_value(),
57
2.54M
      BadSetOnceReassignment,
58
2.54M
      "Attempt to reassign to a SetOnce that already has a value."
59
2.54M
    );
60
61
2.54M
    m_value.emplace(std::move(_newValue));
62
2.54M
    return *this;
63
2.54M
  }
Unexecuted instantiation: solidity::util::SetOnce<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0> >::operator=(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>) &
solidity::util::SetOnce<solidity::frontend::FunctionDefinition const*>::operator=(solidity::frontend::FunctionDefinition const*) &
Line
Count
Source
54
106k
  {
55
106k
    assertThrow(
56
106k
      !m_value.has_value(),
57
106k
      BadSetOnceReassignment,
58
106k
      "Attempt to reassign to a SetOnce that already has a value."
59
106k
    );
60
61
106k
    m_value.emplace(std::move(_newValue));
62
106k
    return *this;
63
106k
  }
solidity::util::SetOnce<solidity::frontend::FunctionCallKind>::operator=(solidity::frontend::FunctionCallKind) &
Line
Count
Source
54
36.9k
  {
55
36.9k
    assertThrow(
56
36.9k
      !m_value.has_value(),
57
36.9k
      BadSetOnceReassignment,
58
36.9k
      "Attempt to reassign to a SetOnce that already has a value."
59
36.9k
    );
60
61
36.9k
    m_value.emplace(std::move(_newValue));
62
36.9k
    return *this;
63
36.9k
  }
solidity::util::SetOnce<solidity::frontend::VirtualLookup>::operator=(solidity::frontend::VirtualLookup) &
Line
Count
Source
54
332k
  {
55
332k
    assertThrow(
56
332k
      !m_value.has_value(),
57
332k
      BadSetOnceReassignment,
58
332k
      "Attempt to reassign to a SetOnce that already has a value."
59
332k
    );
60
61
332k
    m_value.emplace(std::move(_newValue));
62
332k
    return *this;
63
332k
  }
64
65
  /// @return A reference to the stored value. The returned reference has the same lifetime as `*this`.
66
  /// @throws BadSetOnceAccess when the stored value has not yet been set
67
  T const& operator*() const
68
2.38M
  {
69
2.38M
    assertThrow(
70
2.38M
      m_value.has_value(),
71
2.38M
      BadSetOnceAccess,
72
2.38M
      "Attempt to access the value of a SetOnce that does not have a value."
73
2.38M
    );
74
75
2.38M
    return m_value.value();
76
2.38M
  }
solidity::util::SetOnce<std::__1::shared_ptr<solidity::frontend::CallGraph const> >::operator*() const
Line
Count
Source
68
353k
  {
69
353k
    assertThrow(
70
353k
      m_value.has_value(),
71
353k
      BadSetOnceAccess,
72
353k
      "Attempt to access the value of a SetOnce that does not have a value."
73
353k
    );
74
75
353k
    return m_value.value();
76
353k
  }
solidity::util::SetOnce<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::operator*() const
Line
Count
Source
68
293k
  {
69
293k
    assertThrow(
70
293k
      m_value.has_value(),
71
293k
      BadSetOnceAccess,
72
293k
      "Attempt to access the value of a SetOnce that does not have a value."
73
293k
    );
74
75
293k
    return m_value.value();
76
293k
  }
solidity::util::SetOnce<bool>::operator*() const
Line
Count
Source
68
631k
  {
69
631k
    assertThrow(
70
631k
      m_value.has_value(),
71
631k
      BadSetOnceAccess,
72
631k
      "Attempt to access the value of a SetOnce that does not have a value."
73
631k
    );
74
75
631k
    return m_value.value();
76
631k
  }
solidity::util::SetOnce<std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::vector<solidity::frontend::Declaration const*, std::__1::allocator<solidity::frontend::Declaration const*> >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, std::__1::vector<solidity::frontend::Declaration const*, std::__1::allocator<solidity::frontend::Declaration const*> > > > > >::operator*() const
Line
Count
Source
68
46.4k
  {
69
46.4k
    assertThrow(
70
46.4k
      m_value.has_value(),
71
46.4k
      BadSetOnceAccess,
72
46.4k
      "Attempt to access the value of a SetOnce that does not have a value."
73
46.4k
    );
74
75
46.4k
    return m_value.value();
76
46.4k
  }
solidity::util::SetOnce<solidity::frontend::FunctionCallKind>::operator*() const
Line
Count
Source
68
460k
  {
69
460k
    assertThrow(
70
460k
      m_value.has_value(),
71
460k
      BadSetOnceAccess,
72
460k
      "Attempt to access the value of a SetOnce that does not have a value."
73
460k
    );
74
75
460k
    return m_value.value();
76
460k
  }
solidity::util::SetOnce<solidity::frontend::VirtualLookup>::operator*() const
Line
Count
Source
68
81.0k
  {
69
81.0k
    assertThrow(
70
81.0k
      m_value.has_value(),
71
81.0k
      BadSetOnceAccess,
72
81.0k
      "Attempt to access the value of a SetOnce that does not have a value."
73
81.0k
    );
74
75
81.0k
    return m_value.value();
76
81.0k
  }
solidity::util::SetOnce<solidity::frontend::FunctionDefinition const*>::operator*() const
Line
Count
Source
68
516k
  {
69
516k
    assertThrow(
70
516k
      m_value.has_value(),
71
516k
      BadSetOnceAccess,
72
516k
      "Attempt to access the value of a SetOnce that does not have a value."
73
516k
    );
74
75
516k
    return m_value.value();
76
516k
  }
Unexecuted instantiation: solidity::util::SetOnce<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0> >::operator*() const
77
78
  /// @return A reference to the stored value. The referent of the returned pointer has the same lifetime as `*this`.
79
  /// @throws BadSetOnceAccess when the stored value has not yet been set
80
45.3k
  T const* operator->() const { return std::addressof(**this); }
81
82
  /// @return true if a value was assigned
83
789k
  bool set() const { return m_value.has_value(); }
solidity::util::SetOnce<std::__1::shared_ptr<solidity::frontend::CallGraph const> >::set() const
Line
Count
Source
83
437k
  bool set() const { return m_value.has_value(); }
solidity::util::SetOnce<bool>::set() const
Line
Count
Source
83
351k
  bool set() const { return m_value.has_value(); }
Unexecuted instantiation: solidity::util::SetOnce<std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::vector<solidity::frontend::Declaration const*, std::__1::allocator<solidity::frontend::Declaration const*> >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, std::__1::vector<solidity::frontend::Declaration const*, std::__1::allocator<solidity::frontend::Declaration const*> > > > > >::set() const
Unexecuted instantiation: solidity::util::SetOnce<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::set() const
Unexecuted instantiation: solidity::util::SetOnce<solidity::frontend::FunctionDefinition const*>::set() const
Unexecuted instantiation: solidity::util::SetOnce<solidity::frontend::FunctionCallKind>::set() const
84
private:
85
  std::optional<T> m_value = std::nullopt;
86
};
87
88
}