lazy_init.hpp
Go to the documentation of this file.
1 // Copyright (C) 2020-2024 Jonathan Müller and lexy contributors
2 // SPDX-License-Identifier: BSL-1.0
3 
4 #ifndef LEXY_DETAIL_LAZY_INIT_HPP_INCLUDED
5 #define LEXY_DETAIL_LAZY_INIT_HPP_INCLUDED
6 
9 #include <lexy/_detail/std.hpp>
10 
11 namespace lexy::_detail
12 {
13 template <typename T>
15 {
16  bool _init;
17  union
18  {
19  char _empty;
20  T _value;
21  };
22 
23  constexpr _lazy_init_storage_trivial() noexcept : _init(false), _empty() {}
24 
25  template <typename... Args>
26  constexpr _lazy_init_storage_trivial(int, Args&&... args)
27  : _init(true), _value(LEXY_FWD(args)...)
28  {}
29 
30  template <typename... Args>
31  constexpr void _construct(Args&&... args)
32  {
33  *this = _lazy_init_storage_trivial(0, LEXY_FWD(args)...);
34  }
35 };
36 
37 template <typename T>
39 {
40  bool _init;
41  union
42  {
43  char _empty;
44  T _value;
45  };
46 
47  constexpr _lazy_init_storage_non_trivial() noexcept : _init(false), _empty() {}
48 
49  template <typename... Args>
50  LEXY_CONSTEXPR_DTOR void _construct(Args&&... args)
51  {
53  _init = true;
54  }
55 
56  // Cannot add noexcept due to https://github.com/llvm/llvm-project/issues/59854.
58  {
59  if (_init)
60  _value.~T();
61  }
62 
64  _lazy_init_storage_non_trivial&& other) noexcept
65  : _init(other._init), _empty()
66  {
67  if (_init)
68  _detail::construct_at(&_value, LEXY_MOV(other._value));
69  }
70 
72  _lazy_init_storage_non_trivial&& other) noexcept
73  {
74  if (_init && other._init)
75  _value = LEXY_MOV(other._value);
76  else if (_init && !other._init)
77  {
78  _value.~T();
79  _init = false;
80  }
81  else if (!_init && other._init)
82  {
83  _detail::construct_at(&_value, LEXY_MOV(other._value));
84  _init = true;
85  }
86  else
87  {
88  // Both not initialized, nothing to do.
89  }
90 
91  return *this;
92  }
93 };
94 
95 template <typename T>
96 constexpr auto _lazy_init_trivial = [] {
97  // https://www.foonathan.net/2021/03/trivially-copyable/
98  return std::is_trivially_destructible_v<T> //
99  && std::is_trivially_copy_constructible_v<T> //
100  && std::is_trivially_copy_assignable_v<T> //
101  && std::is_trivially_move_constructible_v<T> //
102  && std::is_trivially_move_assignable_v<T>;
103 }();
104 template <typename T>
105 using _lazy_init_storage = std::conditional_t<_lazy_init_trivial<T>, _lazy_init_storage_trivial<T>,
107 
108 template <typename T>
110 {
111 public:
112  using value_type = T;
113 
114  constexpr lazy_init() noexcept = default;
115 
116  template <typename... Args>
117  constexpr T& emplace(Args&&... args)
118  {
119  if (*this)
120  this->_value = T(LEXY_FWD(args)...);
121  else
122  this->_construct(LEXY_FWD(args)...);
123 
124  return this->_value;
125  }
126 
127  template <typename Fn, typename... Args>
128  constexpr T& emplace_result(Fn&& fn, Args&&... args)
129  {
130  return emplace(LEXY_FWD(fn)(LEXY_FWD(args)...));
131  }
132 
133  constexpr explicit operator bool() const noexcept
134  {
135  return this->_init;
136  }
137 
138  constexpr T& operator*() & noexcept
139  {
140  LEXY_PRECONDITION(*this);
141  return this->_value;
142  }
143  constexpr const T& operator*() const& noexcept
144  {
145  LEXY_PRECONDITION(*this);
146  return this->_value;
147  }
148  constexpr T&& operator*() && noexcept
149  {
150  LEXY_PRECONDITION(*this);
151  return LEXY_MOV(this->_value);
152  }
153  constexpr const T&& operator*() const&& noexcept
154  {
155  LEXY_PRECONDITION(*this);
156  return LEXY_MOV(this->_value);
157  }
158 
159  constexpr T* operator->() noexcept
160  {
161  LEXY_PRECONDITION(*this);
162  return &this->_value;
163  }
164  constexpr const T* operator->() const noexcept
165  {
166  LEXY_PRECONDITION(*this);
167  return &this->_value;
168  }
169 
170 private:
171  template <typename... Args>
172  constexpr explicit lazy_init(int, Args&&... args) noexcept
173  : _lazy_init_storage<T>(0, LEXY_FWD(args)...)
174  {}
175 };
176 template <typename T>
177 class lazy_init<T&>
178 {
179 public:
180  using value_type = T&;
181 
182  constexpr lazy_init() noexcept : _ptr(nullptr) {}
183 
184  constexpr T& emplace(T& ref)
185  {
186  _ptr = &ref;
187  return ref;
188  }
189 
190  template <typename Fn, typename... Args>
191  constexpr T& emplace_result(Fn&& fn, Args&&... args)
192  {
193  return emplace(LEXY_FWD(fn)(LEXY_FWD(args)...));
194  }
195 
196  constexpr explicit operator bool() const noexcept
197  {
198  return _ptr != nullptr;
199  }
200 
201  constexpr T& operator*() const noexcept
202  {
203  LEXY_PRECONDITION(*this);
204  return *_ptr;
205  }
206 
207  constexpr T* operator->() const noexcept
208  {
209  LEXY_PRECONDITION(*this);
210  return _ptr;
211  }
212 
213 private:
214  T* _ptr;
215 };
216 template <>
218 {
219 public:
220  using value_type = void;
221 
222  constexpr lazy_init() noexcept : _init(false) {}
223 
224  constexpr void emplace()
225  {
226  _init = true;
227  }
228  template <typename Fn, typename... Args>
229  constexpr void emplace_result(Fn&& fn, Args&&... args)
230  {
231  LEXY_FWD(fn)(LEXY_FWD(args)...);
232  _init = true;
233  }
234 
235  constexpr explicit operator bool() const noexcept
236  {
237  return _init;
238  }
239 
240 private:
241  bool _init;
242 };
243 } // namespace lexy::_detail
244 
245 #endif // LEXY_DETAIL_LAZY_INIT_HPP_INCLUDED
246 
LEXY_MOV
#define LEXY_MOV(...)
Definition: config.hpp:29
lexy::_detail::lazy_init< T & >::lazy_init
constexpr lazy_init() noexcept
Definition: lazy_init.hpp:182
lexy::_detail::lazy_init< T & >::operator->
constexpr T * operator->() const noexcept
Definition: lazy_init.hpp:207
lexy::_detail::lazy_init::operator*
constexpr T && operator*() &&noexcept
Definition: lazy_init.hpp:148
lexy::_detail::_lazy_init_storage_trivial::_value
T _value
Definition: lazy_init.hpp:20
config.hpp
lexy::_detail::lazy_init::operator*
constexpr const T && operator*() const &&noexcept
Definition: lazy_init.hpp:153
lexy::_detail::_lazy_init_storage_trivial::_construct
constexpr void _construct(Args &&... args)
Definition: lazy_init.hpp:31
lexy::_detail::lazy_init::lazy_init
constexpr lazy_init(int, Args &&... args) noexcept
Definition: lazy_init.hpp:172
lexy::_construct
Definition: object.hpp:24
lexy::_detail::_lazy_init_storage_non_trivial::_lazy_init_storage_non_trivial
LEXY_CONSTEXPR_DTOR _lazy_init_storage_non_trivial(_lazy_init_storage_non_trivial &&other) noexcept
Definition: lazy_init.hpp:63
lexy::_detail::_lazy_init_storage_non_trivial::~_lazy_init_storage_non_trivial
LEXY_CONSTEXPR_DTOR ~_lazy_init_storage_non_trivial()
Definition: lazy_init.hpp:57
LEXY_CONSTEXPR_DTOR
#define LEXY_CONSTEXPR_DTOR
Definition: config.hpp:113
lexy::_detail::lazy_init< void >::emplace_result
constexpr void emplace_result(Fn &&fn, Args &&... args)
Definition: lazy_init.hpp:229
lexy::_detail::lazy_init< void >::value_type
void value_type
Definition: lazy_init.hpp:220
LEXY_FWD
#define LEXY_FWD(...)
Definition: config.hpp:30
lexy::_detail::_lazy_init_storage_non_trivial
Definition: lazy_init.hpp:38
lexy::_detail::lazy_init::emplace_result
constexpr T & emplace_result(Fn &&fn, Args &&... args)
Definition: lazy_init.hpp:128
std.hpp
LEXY_PRECONDITION
#define LEXY_PRECONDITION(Expr)
Definition: assert.hpp:36
lexy::_detail::_lazy_init_storage_trivial::_init
bool _init
Definition: lazy_init.hpp:16
lexy::_detail::lazy_init< void >::_init
bool _init
Definition: lazy_init.hpp:241
detail::void
j template void())
Definition: json.hpp:4893
lexy::_detail::_lazy_init_storage_trivial::_lazy_init_storage_trivial
constexpr _lazy_init_storage_trivial() noexcept
Definition: lazy_init.hpp:23
lexy::_detail::lazy_init::operator->
constexpr const T * operator->() const noexcept
Definition: lazy_init.hpp:164
lexy::_detail::lazy_init::emplace
constexpr T & emplace(Args &&... args)
Definition: lazy_init.hpp:117
lexy::_detail::lazy_init
Definition: lazy_init.hpp:109
lexy::_detail::lazy_init< T & >::emplace_result
constexpr T & emplace_result(Fn &&fn, Args &&... args)
Definition: lazy_init.hpp:191
lexy::_detail::_lazy_init_storage_non_trivial::operator=
LEXY_CONSTEXPR_DTOR _lazy_init_storage_non_trivial & operator=(_lazy_init_storage_non_trivial &&other) noexcept
Definition: lazy_init.hpp:71
assert.hpp
lexy::_detail::_lazy_init_storage_non_trivial::_construct
LEXY_CONSTEXPR_DTOR void _construct(Args &&... args)
Definition: lazy_init.hpp:50
lexy::_detail::_lazy_init_storage
std::conditional_t< _lazy_init_trivial< T >, _lazy_init_storage_trivial< T >, _lazy_init_storage_non_trivial< T > > _lazy_init_storage
Definition: lazy_init.hpp:106
lexy::_detail::_lazy_init_storage_trivial
Definition: lazy_init.hpp:14
lexy::_detail::_lazy_init_storage_non_trivial::_value
T _value
Definition: lazy_init.hpp:44
lexy::_detail
Definition: any_ref.hpp:12
lexy::_detail::_lazy_init_storage_non_trivial::_lazy_init_storage_non_trivial
constexpr _lazy_init_storage_non_trivial() noexcept
Definition: lazy_init.hpp:47
lexy::_detail::_lazy_init_storage_trivial::_lazy_init_storage_trivial
constexpr _lazy_init_storage_trivial(int, Args &&... args)
Definition: lazy_init.hpp:26
lexy::_detail::lazy_init::operator->
constexpr T * operator->() noexcept
Definition: lazy_init.hpp:159
lexy::_detail::lazy_init::operator*
constexpr T & operator*() &noexcept
Definition: lazy_init.hpp:138
lexy::_detail::lazy_init< T & >::emplace
constexpr T & emplace(T &ref)
Definition: lazy_init.hpp:184
lexy::_detail::_lazy_init_trivial
constexpr auto _lazy_init_trivial
Definition: lazy_init.hpp:96
lexy::_detail::lazy_init::lazy_init
constexpr lazy_init() noexcept=default
lexy::_detail::lazy_init< T & >::value_type
T & value_type
Definition: lazy_init.hpp:180
lexy::_detail::lazy_init< T & >::operator*
constexpr T & operator*() const noexcept
Definition: lazy_init.hpp:201
lexy::_detail::lazy_init< void >::emplace
constexpr void emplace()
Definition: lazy_init.hpp:224
lexy::_detail::lazy_init< void >::lazy_init
constexpr lazy_init() noexcept
Definition: lazy_init.hpp:222
lexy::_detail::_lazy_init_storage_non_trivial::_empty
char _empty
Definition: lazy_init.hpp:43
lexy::_detail::_lazy_init_storage_trivial::_empty
char _empty
Definition: lazy_init.hpp:19
lexy::_detail::_lazy_init_storage_non_trivial::_init
bool _init
Definition: lazy_init.hpp:40
lexy::_detail::lazy_init::operator*
constexpr const T & operator*() const &noexcept
Definition: lazy_init.hpp:143
lexy::input_location_anchor
Anchor for the location search.
Definition: input_location.hpp:17
lexy::_detail::construct_at
T * construct_at(T *ptr, Args &&... args)
Definition: std.hpp:46
lexy::_ptr
Definition: parse_tree_input.hpp:71
lexy::_detail::lazy_init< T & >::_ptr
T * _ptr
Definition: lazy_init.hpp:214


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Fri Dec 13 2024 03:19:17