@@ -151,6 +151,154 @@ size_t minisketch_compute_max_elements(uint32_t bits, size_t capacity, uint32_t
151151
152152#ifdef __cplusplus
153153}
154- #endif
155154
156- #endif
155+ #if __cplusplus >= 201103L
156+ #include < memory>
157+ #include < vector>
158+ #if __cplusplus >= 201703L
159+ #include < optional>
160+ #endif // __cplusplus >= 201703L
161+ #include < cassert>
162+
163+ /* * Simple RAII C++11 wrapper around the minisketch API. */
164+ class Minisketch
165+ {
166+ struct Deleter
167+ {
168+ void operator ()(minisketch* ptr) const
169+ {
170+ minisketch_destroy (ptr);
171+ }
172+ };
173+
174+ std::unique_ptr<minisketch, Deleter> m_minisketch;
175+
176+ public:
177+ /* * See minisketch_bits_supported(). */
178+ static bool BitsSupported (uint32_t bits) { return minisketch_bits_supported (bits); }
179+
180+ /* * See minisketch_implementation_max(). */
181+ static uint32_t MaxImplementation () { return minisketch_implementation_max (); }
182+
183+ /* * See minisketch_compute_capacity(). */
184+ static size_t ComputeCapacity (uint32_t bits, size_t max_elements, uint32_t fpbits) { return minisketch_compute_capacity (bits, max_elements, fpbits); }
185+
186+ /* * See minisketch_compute_max_elements(). */
187+ static size_t ComputeMaxElements (uint32_t bits, size_t capacity, uint32_t fpbits) { return minisketch_compute_max_elements (bits, capacity, fpbits); }
188+
189+ /* * Construct a clone of the specified sketch. */
190+ Minisketch (const Minisketch& sketch)
191+ {
192+ m_minisketch = std::unique_ptr<minisketch, Deleter>(minisketch_clone (sketch.m_minisketch .get ()));
193+ }
194+
195+ /* * Make this Minisketch a clone of the specified one. */
196+ Minisketch& operator =(const Minisketch& sketch)
197+ {
198+ m_minisketch = std::unique_ptr<minisketch, Deleter>(minisketch_clone (sketch.m_minisketch .get ()));
199+ return *this ;
200+ }
201+
202+ Minisketch () = default ;
203+ Minisketch (Minisketch&&) = default ;
204+ Minisketch& operator =(Minisketch&&) = default ;
205+
206+ /* * Construct a Minisketch object with the specified parameters. */
207+ Minisketch (uint32_t bits, uint32_t implementation, size_t capacity)
208+ {
209+ m_minisketch = std::unique_ptr<minisketch, Deleter>(minisketch_create (bits, implementation, capacity));
210+ }
211+
212+ /* * Create a Minisketch object sufficiently large for the specified number of elements at given fpbits. */
213+ static Minisketch CreateFP (uint32_t bits, uint32_t implementation, size_t max_elements, uint32_t fpbits)
214+ {
215+ return Minisketch (bits, implementation, ComputeCapacity (bits, max_elements, fpbits));
216+ }
217+
218+ /* * See minisketch_get_bits(). */
219+ uint32_t GetBits () const { return minisketch_bits (m_minisketch.get ()); }
220+
221+ /* * See minisketch_get_capacity(). */
222+ size_t GetCapacity () const { return minisketch_capacity (m_minisketch.get ()); }
223+
224+ /* * See minisketch_get_implementation(). */
225+ uint32_t GetImplementation () const { return minisketch_implementation (m_minisketch.get ()); }
226+
227+ /* * See minisketch_set_seed(). */
228+ Minisketch& SetSeed (uint64_t seed)
229+ {
230+ minisketch_set_seed (m_minisketch.get (), seed);
231+ return *this ;
232+ }
233+
234+ /* * See miniksetch_add_element(). */
235+ Minisketch& Add (uint64_t element)
236+ {
237+ minisketch_add_uint64 (m_minisketch.get (), element);
238+ return *this ;
239+ }
240+
241+ /* * See minisketch_merge(). */
242+ Minisketch& Merge (const Minisketch& sketch)
243+ {
244+ minisketch_merge (m_minisketch.get (), sketch.m_minisketch .get ());
245+ return *this ;
246+ }
247+
248+ /* * Decode this sketch into the result vector, which must have a size equal to the maximum allowed elements. */
249+ bool Decode (std::vector<uint64_t >& result) const
250+ {
251+ ssize_t ret = minisketch_decode (m_minisketch.get (), result.size (), result.data ());
252+ if (ret == -1 ) return false ;
253+ result.resize (ret);
254+ return true ;
255+ }
256+
257+ /* * See minisketch_serialized_size(). */
258+ size_t GetSerializedSize () const { return minisketch_serialized_size (m_minisketch.get ()); }
259+
260+ /* * Serialize the sketch as a byte vector. */
261+ std::vector<unsigned char > Serialize () const
262+ {
263+ std::vector<unsigned char > result (GetSerializedSize ());
264+ minisketch_serialize (m_minisketch.get (), result.data ());
265+ return result;
266+ }
267+
268+ /* * Deserialize into this sketch from an object containing its bytes (which has data() and size() members). */
269+ template <typename T>
270+ Minisketch& Deserialize (
271+ const T& obj,
272+ typename std::enable_if<
273+ std::is_convertible<typename std::remove_pointer<decltype (obj.data())>::type (*)[], const unsigned char (*)[]>::value &&
274+ std::is_convertible<decltype(obj.size()), std::size_t>::value,
275+ std::nullptr_t
276+ >::type = nullptr)
277+ {
278+ assert (GetSerializedSize () == obj.size ());
279+ minisketch_deserialize (m_minisketch.get (), obj.data ());
280+ return *this ;
281+ }
282+
283+ #if __cplusplus >= 201703L
284+ /* * C++17 only: decode with a specified number of max elements into an optional vector. */
285+ std::optional<std::vector<uint64_t >> Decode (size_t max_elements) const
286+ {
287+ std::vector<uint64_t > result (max_elements);
288+ ssize_t ret = minisketch_decode (m_minisketch.get (), max_elements, result.data ());
289+ if (ret == -1 ) return {};
290+ result.resize (ret);
291+ return std::move (result);
292+ }
293+
294+ /* * C++17 only: decode with a specified fpbits into an optional vector. */
295+ std::optional<std::vector<uint64_t >> DecodeFP (uint32_t fpbits) const
296+ {
297+ return Decode (ComputeMaxElements (GetBits (), GetCapacity (), fpbits));
298+ }
299+ #endif // __cplusplus >= 201703L
300+ };
301+ #endif // __cplusplus >= 201103L
302+ #endif // __cplusplus
303+
304+ #endif // _MINISKETCH_H_
0 commit comments