joque
task orchestration library
list_ptr.hpp
Go to the documentation of this file.
1 #pragma once
23 
24 #include <concepts>
25 #include <cstddef>
26 #include <cstdint>
27 
28 namespace joque::bits
29 {
30 
31 template < typename Node, typename Header, typename Accessor >
32 class list_ptr
33 {
34 public:
35  enum class mark : std::uintptr_t
36  {
37  NODE_TYPE = 0x00,
38  HEADER_TYPE = 0x01,
39  NULL_TYPE = 0x02
40  };
41 
42  using node_type = Node;
43  using header_type = Header;
44  using accessor_type = Accessor;
45 
46  list_ptr() noexcept = default;
47 
48  list_ptr( std::nullptr_t ) noexcept
49  {
50  }
51 
52  list_ptr( Node* item ) noexcept
53  : ptr_( item )
54  {
55  }
56 
57  list_ptr( Header* item ) noexcept
58  {
59  if ( item != nullptr ) {
60  auto raw = reinterpret_cast< std::uintptr_t >( item ) | 0x01;
61  ptr_ = reinterpret_cast< void* >( raw );
62  }
63  }
64 
65  [[nodiscard]] mark type() const
66  {
67  static_assert( alignof( Node ) > 1 );
68  static_assert( alignof( Header ) > 1 );
69  if ( ptr_ == nullptr )
70  return mark::NULL_TYPE;
71  if ( ctlbit() )
72  return mark::HEADER_TYPE;
73  return mark::NODE_TYPE;
74  }
75 
76  template < typename K >
77  K* get()
78  {
79  return get_impl< K, K >( *this );
80  }
81 
82  template < typename K >
83  [[nodiscard]] const K* get() const
84  {
85  return get_impl< const K, K >( *this );
86  }
87 
88  Node* get_node()
89  {
90  return get_impl< Node, Node >( *this );
91  }
92 
93  [[nodiscard]] const Node* get_node() const
94  {
95  return get_impl< const Node, Node >( *this );
96  }
97 
98  Header* find_header()
99  {
100  return find_header_impl< Header >( *this );
101  }
102 
103  [[nodiscard]] const Header* find_header() const
104  {
105  return find_header_impl< const Header >( *this );
106  }
107 
108  void match( auto&& tf, auto&& uf )
109  {
110  match_impl( *this, tf, uf );
111  }
112 
113  void match( auto&& tf, auto&& uf ) const
114  {
115  match_impl( *this, tf, uf );
116  }
117 
118  bool operator==( std::nullptr_t ) const
119  {
120  return ptr_ == nullptr;
121  }
122 
123  bool operator==( const list_ptr& other ) const = default;
124  auto operator<=>( const list_ptr& other ) const = default;
125 
126 private:
127  template < typename RetType, typename K >
128  static RetType* get_impl( auto& self )
129  {
130  static_assert( std::same_as< K, Header > || std::same_as< K, Node > );
131 
132  if constexpr ( std::same_as< K, Header > ) {
133  if ( self.type() == mark::HEADER_TYPE )
134  return reinterpret_cast< RetType* >( self.pure_ptr() );
135  } else {
136  if ( self.type() == mark::NODE_TYPE )
137  return reinterpret_cast< RetType* >( self.pure_ptr() );
138  }
139  return nullptr;
140  }
141 
142  static void match_impl( auto& self, auto&& tf, auto&& uf )
143  {
144  if ( auto* ptr = self.template get< Header >() )
145  uf( *ptr );
146  else if ( auto* ptr = self.get_node() )
147  tf( *ptr );
148  }
149 
150  template < typename RetType >
151  static RetType* find_header_impl( auto& self )
152  {
153  if ( auto* ptr = self.template get< Header >() )
154  return ptr;
155  else if ( auto* ptr = self.get_node() )
156  return &Accessor::get( *ptr );
157  return nullptr;
158  }
159 
160  [[nodiscard]] uint8_t ctlbit() const
161  {
162  return reinterpret_cast< std::uintptr_t >( ptr_ ) & 0x01;
163  }
164 
165  static constexpr std::uintptr_t mask = ~static_cast< std::uintptr_t >( 0x01 );
166 
167  [[nodiscard]] void* pure_ptr() const
168  {
169  auto raw = reinterpret_cast< std::uintptr_t >( ptr_ );
170  raw = raw & mask;
171  return reinterpret_cast< void* >( raw );
172  }
173 
174  void* ptr_ = nullptr;
175 };
176 
177 } // namespace joque::bits
Definition: list_ptr.hpp:33
mark type() const
Definition: list_ptr.hpp:65
void match(auto &&tf, auto &&uf) const
Definition: list_ptr.hpp:113
K * get()
Definition: list_ptr.hpp:77
mark
Definition: list_ptr.hpp:36
const Header * find_header() const
Definition: list_ptr.hpp:103
Node * get_node()
Definition: list_ptr.hpp:88
list_ptr(Node *item) noexcept
Definition: list_ptr.hpp:52
auto operator<=>(const list_ptr &other) const =default
list_ptr() noexcept=default
Accessor accessor_type
Definition: list_ptr.hpp:44
Header header_type
Definition: list_ptr.hpp:43
bool operator==(std::nullptr_t) const
Definition: list_ptr.hpp:118
const K * get() const
Definition: list_ptr.hpp:83
bool operator==(const list_ptr &other) const =default
const Node * get_node() const
Definition: list_ptr.hpp:93
list_ptr(Header *item) noexcept
Definition: list_ptr.hpp:57
Header * find_header()
Definition: list_ptr.hpp:98
Node node_type
Definition: list_ptr.hpp:42
void match(auto &&tf, auto &&uf)
Definition: list_ptr.hpp:108
MIT License.
Definition: dag.hpp:27