stateless_lambda.hpp
Go to the documentation of this file.
1 // Copyright (C) 2020-2023 Jonathan Müller and lexy contributors
2 // SPDX-License-Identifier: BSL-1.0
3 
4 #ifndef LEXY_DETAIL_STATELESS_LAMBDA_HPP_INCLUDED
5 #define LEXY_DETAIL_STATELESS_LAMBDA_HPP_INCLUDED
6 
8 
9 namespace lexy::_detail
10 {
11 template <typename Lambda>
13 {
14  static_assert(std::is_class_v<Lambda>);
15  static_assert(std::is_empty_v<Lambda>);
16 
17  static constexpr Lambda get()
18  {
19  if constexpr (std::is_default_constructible_v<Lambda>)
20  {
21  // We're using C++20, lambdas are default constructible.
22  return Lambda();
23  }
24  else
25  {
26  // We're not having C++20; use a sequence of weird workarounds to legally construct a
27  // Lambda object without invoking any constructors.
28  // This works and is well-defined, but sadly not constexpr.
29  // Taken from: https://www.youtube.com/watch?v=yTb6xz_FSkY
30 
31  // We're defining two standard layout types that have a char as a common initial
32  // sequence (as the Lambda is empty, it doesn't add anymore members to B).
33  struct A
34  {
35  char member;
36  };
37  struct B : Lambda
38  {
39  char member;
40  };
41  static_assert(std::is_standard_layout_v<A> && std::is_standard_layout_v<B>);
42 
43  // We put the two types in a union and initialize the a member, which we can do.
44  union storage_t
45  {
46  A a;
47  B b;
48  } storage{};
49 
50  // We can now take the address of member via b, as it is in the common initial sequence.
51  auto char_ptr = &storage.b.member;
52  // char_ptr is a pointer to the first member of B, so we can reinterpret_cast it to a
53  // pointer to B.
54  auto b_ptr = reinterpret_cast<B*>(char_ptr);
55  // Now we're having a pointer to a B object, which can we can cast to the base class
56  // Lambda.
57  auto lambda_ptr = static_cast<Lambda*>(b_ptr);
58  // Dereference the pointer to get the lambda object.
59  return *lambda_ptr;
60  }
61  }
62 
63  template <typename... Args>
64  constexpr decltype(auto) operator()(Args&&... args) const
65  {
66  return get()(LEXY_FWD(args)...);
67  }
68 };
69 } // namespace lexy::_detail
70 
71 #endif // LEXY_DETAIL_STATELESS_LAMBDA_HPP_INCLUDED
72 
config.hpp
lexy::_detail::stateless_lambda
Definition: stateless_lambda.hpp:12
LEXY_FWD
#define LEXY_FWD(...)
Definition: config.hpp:22
lexyd::member
constexpr auto member
Definition: member.hpp:92
lexy::_detail
Definition: any_ref.hpp:12
lexy::_detail::stateless_lambda::get
static constexpr Lambda get()
Definition: stateless_lambda.hpp:17


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Fri Jun 28 2024 02:20:08