2020#include " ../../phtree/common/common.h"
2121#include " node.h"
2222#include < cassert>
23- #include < cstdint>
2423#include < memory>
25- #include < string>
26- #include < variant>
24+ #include < optional>
2725
2826namespace improbable ::phtree::v16 {
2927
@@ -44,69 +42,85 @@ class Entry {
4442 using NodeT = Node<DIM, T, SCALAR>;
4543
4644 public:
47- Entry () : kd_key_(), value_{std::in_place_type<ValueT>, T{}} {}
48-
4945 /*
5046 * Construct entry with existing node.
5147 */
52- Entry (const KeyT& k, std::unique_ptr<NodeT>&& node)
53- : kd_key_{k}
54- , value_{
55- std::in_place_type<std::unique_ptr<NodeT>>, std::forward<std::unique_ptr<NodeT>>(node)} {}
48+ Entry (const KeyT& k, std::unique_ptr<NodeT>&& node_ptr)
49+ : kd_key_{k}, node_{std::move (node_ptr)}, value_{std::nullopt } {}
5650
5751 /*
5852 * Construct entry with a new node.
5953 */
6054 Entry (bit_width_t infix_len, bit_width_t postfix_len)
61- : kd_key_()
62- , value_{
63- std::in_place_type<std::unique_ptr<NodeT>>,
64- std::make_unique<NodeT>(infix_len, postfix_len)} {}
55+ : kd_key_(), node_{std::make_unique<NodeT>(infix_len, postfix_len)}, value_{std::nullopt } {}
56+
57+ /*
58+ * Construct entry with existing T.
59+ */
60+ Entry (const KeyT& k, std::optional<ValueT>&& value)
61+ : kd_key_{k}, node_{nullptr }, value_{std::move (value)} {}
6562
6663 /*
6764 * Construct entry with new T or moved T.
6865 */
6966 template <typename ... Args>
7067 explicit Entry (const KeyT& k, Args&&... args)
71- : kd_key_{k}, value_{std::in_place_type<ValueT> , std::forward<Args>(args)...} {}
68+ : kd_key_{k}, node_{ nullptr }, value_{std::in_place , std::forward<Args>(args)...} {}
7269
7370 [[nodiscard]] const KeyT& GetKey () const {
7471 return kd_key_;
7572 }
7673
7774 [[nodiscard]] bool IsValue () const {
78- return std::holds_alternative<ValueT>( value_);
75+ return value_. has_value ( );
7976 }
8077
8178 [[nodiscard]] bool IsNode () const {
82- return std::holds_alternative<std::unique_ptr<NodeT>>(value_) ;
79+ return node_. get () != nullptr ;
8380 }
8481
8582 [[nodiscard]] T& GetValue () const {
8683 assert (IsValue ());
87- return const_cast <T&>(std::get<ValueT>( value_) );
84+ return const_cast <T&>(* value_);
8885 }
8986
9087 [[nodiscard]] NodeT& GetNode () const {
9188 assert (IsNode ());
92- return *std::get<std::unique_ptr<NodeT>>(value_);
89+ return *node_;
90+ }
91+
92+ void SetNode (std::unique_ptr<NodeT>&& node) {
93+ assert (!IsNode ());
94+ node_ = std::move (node);
95+ value_.reset ();
96+ }
97+
98+ [[nodiscard]] std::optional<ValueT>&& ExtractValue() {
99+ assert (IsValue ());
100+ return std::move (value_);
101+ }
102+
103+ [[nodiscard]] std::unique_ptr<NodeT>&& ExtractNode() {
104+ assert (IsNode ());
105+ return std::move (node_);
93106 }
94107
95108 void ReplaceNodeWithDataFromEntry (Entry&& other) {
96109 assert (IsNode ());
97110 kd_key_ = other.GetKey ();
98111
99- // 'value_' points indirectly to 'entry' so we have to remove `entity's` content before
100- // assigning anything to `value_` here. Otherwise the assignment would destruct the previous
101- // content and, by reachability, `entity's` content.
102- auto old_node = std::get<std::unique_ptr<NodeT>>(value_). release ( );
103- value_ = std::move (other. value_ );
104- delete old_node;
112+ if (other. IsNode ()) {
113+ node_ = std::move (other. node_ );
114+ } else {
115+ value_ = std::move (other. value_ );
116+ node_. reset ( );
117+ }
105118 }
106119
107120 private:
108121 KeyT kd_key_;
109- std::variant<ValueT, std::unique_ptr<NodeT>> value_;
122+ std::unique_ptr<NodeT> node_;
123+ std::optional<ValueT> value_;
110124};
111125} // namespace improbable::phtree::v16
112126
0 commit comments