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