Coverage Report

Created: 2025-06-24 07:59

/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
4.43M
  SetOnce() = default;
solidity::util::SetOnce<solidity::frontend::VirtualLookup>::SetOnce()
Line
Count
Source
40
431k
  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.1k
  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
28.7k
  SetOnce() = default;
solidity::util::SetOnce<bool>::SetOnce()
Line
Count
Source
40
3.65M
  SetOnce() = default;
solidity::util::SetOnce<std::__1::shared_ptr<solidity::frontend::CallGraph const> >::SetOnce()
Line
Count
Source
40
55.7k
  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
151k
  SetOnce() = default;
solidity::util::SetOnce<solidity::frontend::FunctionCallKind>::SetOnce()
Line
Count
Source
40
43.8k
  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
4.13M
  {
55
4.13M
    assertThrow(
56
4.13M
      !m_value.has_value(),
57
4.13M
      BadSetOnceReassignment,
58
4.13M
      "Attempt to reassign to a SetOnce that already has a value."
59
4.13M
    );
60
61
4.13M
    m_value.emplace(std::move(_newValue));
62
4.13M
    return *this;
63
4.13M
  }
solidity::util::SetOnce<std::__1::shared_ptr<solidity::frontend::CallGraph const> >::operator=(std::__1::shared_ptr<solidity::frontend::CallGraph const>) &
Line
Count
Source
54
34.2k
  {
55
34.2k
    assertThrow(
56
34.2k
      !m_value.has_value(),
57
34.2k
      BadSetOnceReassignment,
58
34.2k
      "Attempt to reassign to a SetOnce that already has a value."
59
34.2k
    );
60
61
34.2k
    m_value.emplace(std::move(_newValue));
62
34.2k
    return *this;
63
34.2k
  }
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.1k
  {
55
70.1k
    assertThrow(
56
70.1k
      !m_value.has_value(),
57
70.1k
      BadSetOnceReassignment,
58
70.1k
      "Attempt to reassign to a SetOnce that already has a value."
59
70.1k
    );
60
61
70.1k
    m_value.emplace(std::move(_newValue));
62
70.1k
    return *this;
63
70.1k
  }
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
27.4k
  {
55
27.4k
    assertThrow(
56
27.4k
      !m_value.has_value(),
57
27.4k
      BadSetOnceReassignment,
58
27.4k
      "Attempt to reassign to a SetOnce that already has a value."
59
27.4k
    );
60
61
27.4k
    m_value.emplace(std::move(_newValue));
62
27.4k
    return *this;
63
27.4k
  }
solidity::util::SetOnce<bool>::operator=(bool) &
Line
Count
Source
54
3.42M
  {
55
3.42M
    assertThrow(
56
3.42M
      !m_value.has_value(),
57
3.42M
      BadSetOnceReassignment,
58
3.42M
      "Attempt to reassign to a SetOnce that already has a value."
59
3.42M
    );
60
61
3.42M
    m_value.emplace(std::move(_newValue));
62
3.42M
    return *this;
63
3.42M
  }
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
116k
  {
55
116k
    assertThrow(
56
116k
      !m_value.has_value(),
57
116k
      BadSetOnceReassignment,
58
116k
      "Attempt to reassign to a SetOnce that already has a value."
59
116k
    );
60
61
116k
    m_value.emplace(std::move(_newValue));
62
116k
    return *this;
63
116k
  }
solidity::util::SetOnce<solidity::frontend::FunctionCallKind>::operator=(solidity::frontend::FunctionCallKind) &
Line
Count
Source
54
42.6k
  {
55
42.6k
    assertThrow(
56
42.6k
      !m_value.has_value(),
57
42.6k
      BadSetOnceReassignment,
58
42.6k
      "Attempt to reassign to a SetOnce that already has a value."
59
42.6k
    );
60
61
42.6k
    m_value.emplace(std::move(_newValue));
62
42.6k
    return *this;
63
42.6k
  }
solidity::util::SetOnce<solidity::frontend::VirtualLookup>::operator=(solidity::frontend::VirtualLookup) &
Line
Count
Source
54
415k
  {
55
415k
    assertThrow(
56
415k
      !m_value.has_value(),
57
415k
      BadSetOnceReassignment,
58
415k
      "Attempt to reassign to a SetOnce that already has a value."
59
415k
    );
60
61
415k
    m_value.emplace(std::move(_newValue));
62
415k
    return *this;
63
415k
  }
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.65M
  {
69
2.65M
    assertThrow(
70
2.65M
      m_value.has_value(),
71
2.65M
      BadSetOnceAccess,
72
2.65M
      "Attempt to access the value of a SetOnce that does not have a value."
73
2.65M
    );
74
75
2.65M
    return m_value.value();
76
2.65M
  }
solidity::util::SetOnce<std::__1::shared_ptr<solidity::frontend::CallGraph const> >::operator*() const
Line
Count
Source
68
335k
  {
69
335k
    assertThrow(
70
335k
      m_value.has_value(),
71
335k
      BadSetOnceAccess,
72
335k
      "Attempt to access the value of a SetOnce that does not have a value."
73
335k
    );
74
75
335k
    return m_value.value();
76
335k
  }
solidity::util::SetOnce<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::operator*() const
Line
Count
Source
68
297k
  {
69
297k
    assertThrow(
70
297k
      m_value.has_value(),
71
297k
      BadSetOnceAccess,
72
297k
      "Attempt to access the value of a SetOnce that does not have a value."
73
297k
    );
74
75
297k
    return m_value.value();
76
297k
  }
solidity::util::SetOnce<bool>::operator*() const
Line
Count
Source
68
828k
  {
69
828k
    assertThrow(
70
828k
      m_value.has_value(),
71
828k
      BadSetOnceAccess,
72
828k
      "Attempt to access the value of a SetOnce that does not have a value."
73
828k
    );
74
75
828k
    return m_value.value();
76
828k
  }
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
45.1k
  {
69
45.1k
    assertThrow(
70
45.1k
      m_value.has_value(),
71
45.1k
      BadSetOnceAccess,
72
45.1k
      "Attempt to access the value of a SetOnce that does not have a value."
73
45.1k
    );
74
75
45.1k
    return m_value.value();
76
45.1k
  }
solidity::util::SetOnce<solidity::frontend::FunctionCallKind>::operator*() const
Line
Count
Source
68
502k
  {
69
502k
    assertThrow(
70
502k
      m_value.has_value(),
71
502k
      BadSetOnceAccess,
72
502k
      "Attempt to access the value of a SetOnce that does not have a value."
73
502k
    );
74
75
502k
    return m_value.value();
76
502k
  }
solidity::util::SetOnce<solidity::frontend::VirtualLookup>::operator*() const
Line
Count
Source
68
95.1k
  {
69
95.1k
    assertThrow(
70
95.1k
      m_value.has_value(),
71
95.1k
      BadSetOnceAccess,
72
95.1k
      "Attempt to access the value of a SetOnce that does not have a value."
73
95.1k
    );
74
75
95.1k
    return m_value.value();
76
95.1k
  }
solidity::util::SetOnce<solidity::frontend::FunctionDefinition const*>::operator*() const
Line
Count
Source
68
545k
  {
69
545k
    assertThrow(
70
545k
      m_value.has_value(),
71
545k
      BadSetOnceAccess,
72
545k
      "Attempt to access the value of a SetOnce that does not have a value."
73
545k
    );
74
75
545k
    return m_value.value();
76
545k
  }
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
42.1k
  T const* operator->() const { return std::addressof(**this); }
81
82
  /// @return true if a value was assigned
83
881k
  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
418k
  bool set() const { return m_value.has_value(); }
solidity::util::SetOnce<bool>::set() const
Line
Count
Source
83
462k
  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
}