Arbiter
Dependency manager library that supports decentralization
Value.h
Go to the documentation of this file.
1 #pragma once
2 
3 #ifndef __cplusplus
4 #error "This file must be compiled as C++."
5 #endif
6 
7 #include <arbiter/Value.h>
8 
9 #include "ToString.h"
10 
11 #include <cassert>
12 #include <functional>
13 #include <memory>
14 #include <ostream>
15 
16 namespace Arbiter {
17 
18 /**
19  * Expresses shared ownership of an opaque user-provided value type, which was
20  * originally described in an ArbiterUserValue.
21  *
22  * `Owner` is a phantom type used to associate the SharedUserValue with its
23  * usage in a particular class. This helps prevent two SharedUserValue instances
24  * from being compared if they represent conceptually different things (which
25  * might crash user code).
26  */
27 template<typename Owner>
29 {
30  public:
31  SharedUserValue () = default;
32 
33  explicit SharedUserValue (ArbiterUserValue value)
35  , _equalTo(value.equalTo)
36  , _lessThan(value.lessThan)
37  , _hash(value.hash)
38  , _createDescription(value.createDescription)
39  {
40  assert(_equalTo);
41  assert(_lessThan);
42  assert(_hash);
43  }
44 
45  bool operator== (const SharedUserValue &other) const
46  {
47  assert(_equalTo == other._equalTo);
48  return _equalTo(data(), other.data());
49  }
50 
51  bool operator!= (const SharedUserValue &other) const
52  {
53  return !(*this == other);
54  }
55 
56  bool operator< (const SharedUserValue &other) const
57  {
58  assert(_lessThan == other._lessThan);
59  return _lessThan(data(), other.data());
60  }
61 
62  bool operator> (const SharedUserValue &other) const
63  {
64  return other < *this;
65  }
66 
67  bool operator>= (const SharedUserValue &other) const
68  {
69  return !(*this < other);
70  }
71 
72  bool operator<= (const SharedUserValue &other) const
73  {
74  return !(*this > other);
75  }
76 
77  void *data () noexcept
78  {
79  return _data.get();
80  }
81 
82  const void *data () const noexcept
83  {
84  return _data.get();
85  }
86 
88  {
89  if (_createDescription) {
91  } else {
92  return "Arbiter::SharedUserValue";
93  }
94  }
95 
96  size_t hash () const
97  {
98  return _hash(data());
99  }
100 
101  private:
102  std::shared_ptr<void> _data;
103  bool (*_equalTo)(const void *first, const void *second);
104  bool (*_lessThan)(const void *first, const void *second);
105  size_t (*_hash)(const void *data);
106  char *(*_createDescription)(const void *data);
107 
108  static void noOpDestructor (void *)
109  {}
110 };
111 
112 /**
113  * Converts an ArbiterUserContext into a shared pointer, automatically invoking
114  * its destructor when the last shared pointer is destructed.
115  */
116 std::shared_ptr<void> shareUserContext (ArbiterUserContext context);
117 
118 } // namespace Arbiter
119 
120 namespace std {
121 
122 template<typename Owner>
123 struct hash<Arbiter::SharedUserValue<Owner>> final
124 {
125  public:
126  size_t operator() (const Arbiter::SharedUserValue<Owner> &value) const
127  {
128  return value.hash();
129  }
130 };
131 
132 } // namespace std
133 
134 template<typename Owner>
135 std::ostream &operator<< (std::ostream &os, const Arbiter::SharedUserValue<Owner> &value)
136 {
137  return os << value.description();
138 }
char *(* createDescription)(const void *data)
An operation to convert this data object to a string.
Definition: Value.h:57
size_t operator()(const Arbiter::SharedUserValue< Owner > &value) const
Definition: Value.h:126
auto makeIteratorRange(const Collection &collection)
Creates an IteratorRange encompassing the entirety of the given read-only collection.
Definition: Iterator.h:45
bool operator!=(const SharedUserValue &other) const
Definition: Value.h:51
void * data() noexcept
Definition: Value.h:77
std::shared_ptr< void > shareUserContext(ArbiterUserContext context)
Converts an ArbiterUserContext into a shared pointer, automatically invoking its destructor when the ...
bool operator>=(const SharedUserValue &other) const
Definition: Value.h:67
bool operator==(const SharedUserValue &other) const
Definition: Value.h:45
bool operator>(const SharedUserValue &other) const
Definition: Value.h:62
SharedUserValue(ArbiterUserValue value)
Definition: Value.h:33
size_t hash() const
Definition: Value.h:96