rrudb 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +1 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +26 -0
  5. data/examples/example.rb +39 -0
  6. data/ext/rudb/NuDB/include/nudb/CMakeLists.txt +104 -0
  7. data/ext/rudb/NuDB/include/nudb/_experimental/basic_seconds_clock.hpp +200 -0
  8. data/ext/rudb/NuDB/include/nudb/_experimental/chrono_util.hpp +58 -0
  9. data/ext/rudb/NuDB/include/nudb/_experimental/test/fail_file.hpp +343 -0
  10. data/ext/rudb/NuDB/include/nudb/_experimental/test/temp_dir.hpp +73 -0
  11. data/ext/rudb/NuDB/include/nudb/_experimental/test/test_store.hpp +451 -0
  12. data/ext/rudb/NuDB/include/nudb/_experimental/test/xor_shift_engine.hpp +105 -0
  13. data/ext/rudb/NuDB/include/nudb/_experimental/util.hpp +288 -0
  14. data/ext/rudb/NuDB/include/nudb/basic_store.hpp +461 -0
  15. data/ext/rudb/NuDB/include/nudb/concepts.hpp +205 -0
  16. data/ext/rudb/NuDB/include/nudb/context.hpp +144 -0
  17. data/ext/rudb/NuDB/include/nudb/create.hpp +117 -0
  18. data/ext/rudb/NuDB/include/nudb/detail/arena.hpp +296 -0
  19. data/ext/rudb/NuDB/include/nudb/detail/bucket.hpp +473 -0
  20. data/ext/rudb/NuDB/include/nudb/detail/buffer.hpp +86 -0
  21. data/ext/rudb/NuDB/include/nudb/detail/bulkio.hpp +196 -0
  22. data/ext/rudb/NuDB/include/nudb/detail/cache.hpp +236 -0
  23. data/ext/rudb/NuDB/include/nudb/detail/endian.hpp +93 -0
  24. data/ext/rudb/NuDB/include/nudb/detail/field.hpp +265 -0
  25. data/ext/rudb/NuDB/include/nudb/detail/format.hpp +630 -0
  26. data/ext/rudb/NuDB/include/nudb/detail/gentex.hpp +259 -0
  27. data/ext/rudb/NuDB/include/nudb/detail/mutex.hpp +26 -0
  28. data/ext/rudb/NuDB/include/nudb/detail/pool.hpp +243 -0
  29. data/ext/rudb/NuDB/include/nudb/detail/store_base.hpp +45 -0
  30. data/ext/rudb/NuDB/include/nudb/detail/stream.hpp +149 -0
  31. data/ext/rudb/NuDB/include/nudb/detail/xxhash.hpp +328 -0
  32. data/ext/rudb/NuDB/include/nudb/error.hpp +257 -0
  33. data/ext/rudb/NuDB/include/nudb/file.hpp +55 -0
  34. data/ext/rudb/NuDB/include/nudb/impl/basic_store.ipp +785 -0
  35. data/ext/rudb/NuDB/include/nudb/impl/context.ipp +241 -0
  36. data/ext/rudb/NuDB/include/nudb/impl/create.ipp +163 -0
  37. data/ext/rudb/NuDB/include/nudb/impl/error.ipp +175 -0
  38. data/ext/rudb/NuDB/include/nudb/impl/posix_file.ipp +248 -0
  39. data/ext/rudb/NuDB/include/nudb/impl/recover.ipp +209 -0
  40. data/ext/rudb/NuDB/include/nudb/impl/rekey.ipp +248 -0
  41. data/ext/rudb/NuDB/include/nudb/impl/verify.ipp +634 -0
  42. data/ext/rudb/NuDB/include/nudb/impl/visit.ipp +96 -0
  43. data/ext/rudb/NuDB/include/nudb/impl/win32_file.ipp +264 -0
  44. data/ext/rudb/NuDB/include/nudb/native_file.hpp +76 -0
  45. data/ext/rudb/NuDB/include/nudb/nudb.hpp +27 -0
  46. data/ext/rudb/NuDB/include/nudb/posix_file.hpp +228 -0
  47. data/ext/rudb/NuDB/include/nudb/progress.hpp +32 -0
  48. data/ext/rudb/NuDB/include/nudb/recover.hpp +73 -0
  49. data/ext/rudb/NuDB/include/nudb/rekey.hpp +110 -0
  50. data/ext/rudb/NuDB/include/nudb/store.hpp +27 -0
  51. data/ext/rudb/NuDB/include/nudb/type_traits.hpp +63 -0
  52. data/ext/rudb/NuDB/include/nudb/verify.hpp +200 -0
  53. data/ext/rudb/NuDB/include/nudb/version.hpp +21 -0
  54. data/ext/rudb/NuDB/include/nudb/visit.hpp +63 -0
  55. data/ext/rudb/NuDB/include/nudb/win32_file.hpp +246 -0
  56. data/ext/rudb/NuDB/include/nudb/xxhasher.hpp +45 -0
  57. data/ext/rudb/extconf.rb +12 -0
  58. data/ext/rudb/rudb.cpp +234 -0
  59. data/lib/rudb/version.rb +3 -0
  60. data/lib/rudb.rb +1 -0
  61. metadata +104 -0
@@ -0,0 +1,461 @@
1
+ //
2
+ // Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
3
+ //
4
+ // Distributed under the Boost Software License, Version 1.0. (See accompanying
5
+ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
+ //
7
+
8
+ #ifndef NUDB_BASIC_STORE_HPP
9
+ #define NUDB_BASIC_STORE_HPP
10
+
11
+ #include <nudb/context.hpp>
12
+ #include <nudb/file.hpp>
13
+ #include <nudb/type_traits.hpp>
14
+ #include <nudb/detail/cache.hpp>
15
+ #include <nudb/detail/gentex.hpp>
16
+ #include <nudb/detail/mutex.hpp>
17
+ #include <nudb/detail/pool.hpp>
18
+ #include <nudb/detail/store_base.hpp>
19
+ #include <boost/optional.hpp>
20
+ #include <chrono>
21
+
22
+ namespace nudb {
23
+
24
+ /** A high performance, insert-only key/value database for SSDs.
25
+
26
+ To create a database first call the @ref create
27
+ free function. Then construct a @ref basic_store and
28
+ call @ref open on it:
29
+
30
+ @code
31
+ error_code ec;
32
+ create<xxhasher>(
33
+ "db.dat", "db.key", "db.log",
34
+ 1, make_salt(), 8, 4096, 0.5f, ec);
35
+ basic_store<xxhasher, native_file> db;
36
+ db.open("db.dat", "db.key", "db.log", ec);
37
+ @endcode
38
+
39
+ @tparam Hasher The hash function to use. This type
40
+ must meet the requirements of @b Hasher.
41
+
42
+ @tparam File The type of File object to use. This type
43
+ must meet the requirements of @b File.
44
+ */
45
+ template<class Hasher, class File>
46
+ class basic_store
47
+ #if ! NUDB_DOXYGEN
48
+ : private detail::store_base
49
+ #endif
50
+ {
51
+ public:
52
+ using hash_type = Hasher;
53
+ using file_type = File;
54
+
55
+ private:
56
+ using clock_type =
57
+ std::chrono::steady_clock;
58
+
59
+ using time_point =
60
+ typename clock_type::time_point;
61
+
62
+ #if ! NUDB_DOXYGEN
63
+ friend class test::context_test;
64
+ #endif
65
+
66
+ struct state
67
+ {
68
+ File df;
69
+ File kf;
70
+ File lf;
71
+ path_type dp;
72
+ path_type kp;
73
+ path_type lp;
74
+ Hasher hasher;
75
+ detail::pool p0;
76
+ detail::pool p1;
77
+ detail::cache c1;
78
+ detail::key_file_header kh;
79
+
80
+ std::size_t rate = 0;
81
+ time_point when = clock_type::now();
82
+
83
+ state(state const&) = delete;
84
+ state& operator=(state const&) = delete;
85
+
86
+ state(state&&) = default;
87
+ state& operator=(state&&) = default;
88
+
89
+ state(File&& df_, File&& kf_, File&& lf_,
90
+ path_type const& dp_, path_type const& kp_,
91
+ path_type const& lp_,
92
+ detail::key_file_header const& kh_);
93
+ };
94
+
95
+ bool open_ = false;
96
+
97
+ // Use optional because some
98
+ // members cannot be default-constructed.
99
+ //
100
+ boost::optional<state> s_; // State of an open database
101
+
102
+ std::size_t frac_; // accumulates load
103
+ std::size_t thresh_; // split threshold
104
+ nbuck_t buckets_; // number of buckets
105
+ nbuck_t modulus_; // hash modulus
106
+
107
+ std::mutex u_; // serializes insert()
108
+ detail::gentex g_;
109
+ boost::shared_mutex m_;
110
+
111
+ error_code ec_;
112
+ std::atomic<bool> ecb_; // `true` when ec_ set
113
+
114
+ std::size_t dataWriteSize_;
115
+ std::size_t logWriteSize_;
116
+
117
+ struct deleter
118
+ {
119
+ deleter() = default;
120
+ deleter(bool) : free_(true) {}
121
+ void operator() (context* p) const
122
+ {
123
+ if (free_)
124
+ delete p;
125
+ }
126
+
127
+ bool free_ = false;
128
+ };
129
+
130
+ std::unique_ptr<context, deleter> ctx_;
131
+
132
+ public:
133
+ /** Default constructor.
134
+
135
+ A default constructed database is initially closed.
136
+ */
137
+ basic_store() : ctx_(new context, true)
138
+ {
139
+ ctx_->start();
140
+ }
141
+
142
+ basic_store(context& ctx) : ctx_(&ctx) {}
143
+
144
+ /// Copy constructor (disallowed)
145
+ basic_store(basic_store const&) = delete;
146
+
147
+ /// Copy assignment (disallowed)
148
+ basic_store& operator=(basic_store const&) = delete;
149
+
150
+ /** Destroy the database.
151
+
152
+ Files are closed, memory is freed, and data that has not been
153
+ committed is discarded. To ensure that all inserted data is
154
+ written, it is necessary to call @ref close before destroying
155
+ the @ref basic_store.
156
+
157
+ This function ignores errors returned by @ref close; to receive
158
+ those errors it is necessary to call @ref close before the
159
+ @ref basic_store is destroyed.
160
+ */
161
+ ~basic_store();
162
+
163
+ /** Returns `true` if the database is open.
164
+
165
+ @par Thread safety
166
+
167
+ Safe to call concurrently with any function
168
+ except @ref open or @ref close.
169
+ */
170
+ bool
171
+ is_open() const
172
+ {
173
+ return open_;
174
+ }
175
+
176
+ /** Return the path to the data file.
177
+
178
+ @par Requirements
179
+
180
+ The database must be open.
181
+
182
+ @par Thread safety
183
+
184
+ Safe to call concurrently with any function
185
+ except @ref open or @ref close.
186
+
187
+ @return The data file path.
188
+ */
189
+ path_type const&
190
+ dat_path() const;
191
+
192
+ /** Return the path to the key file.
193
+
194
+ @par Requirements
195
+
196
+ The database must be open.
197
+
198
+ @par Thread safety
199
+
200
+ Safe to call concurrently with any function
201
+ except @ref open or @ref close.
202
+
203
+ @return The key file path.
204
+ */
205
+ path_type const&
206
+ key_path() const;
207
+
208
+ /** Return the path to the log file.
209
+
210
+ @par Requirements
211
+
212
+ The database must be open.
213
+
214
+ @par Thread safety
215
+
216
+ Safe to call concurrently with any function
217
+ except @ref open or @ref close.
218
+
219
+ @return The log file path.
220
+ */
221
+ path_type const&
222
+ log_path() const;
223
+
224
+ /** Return the appnum associated with the database.
225
+
226
+ This is an unsigned 64-bit integer associated with the
227
+ database and defined by the application. It is set
228
+ once when the database is created in a call to
229
+ @ref create.
230
+
231
+ @par Requirements
232
+
233
+ The database must be open.
234
+
235
+ @par Thread safety
236
+
237
+ Safe to call concurrently with any function
238
+ except @ref open or @ref close.
239
+
240
+ @return The appnum.
241
+ */
242
+ std::uint64_t
243
+ appnum() const;
244
+
245
+ /** Return the key size associated with the database.
246
+
247
+ The key size is defined by the application when the
248
+ database is created in a call to @ref create. The
249
+ key size cannot be changed on an existing database.
250
+
251
+ @par Requirements
252
+
253
+ The database must be open.
254
+
255
+ @par Thread safety
256
+
257
+ Safe to call concurrently with any function
258
+ except @ref open or @ref close.
259
+
260
+ @return The size of keys in the database.
261
+ */
262
+ std::size_t
263
+ key_size() const;
264
+
265
+ /** Return the block size associated with the database.
266
+
267
+ The block size is defined by the application when the
268
+ database is created in a call to @ref create or when a
269
+ key file is regenerated in a call to @ref rekey. The
270
+ block size cannot be changed on an existing key file.
271
+ Instead, a new key file may be created with a different
272
+ block size.
273
+
274
+ @par Requirements
275
+
276
+ The database must be open.
277
+
278
+ @par Thread safety
279
+
280
+ Safe to call concurrently with any function
281
+ except @ref open or @ref close.
282
+
283
+ @return The size of blocks in the key file.
284
+ */
285
+ std::size_t
286
+ block_size() const;
287
+
288
+ /** Close the database.
289
+
290
+ All data is committed before closing.
291
+
292
+ If an error occurs, the database is still closed.
293
+
294
+ @par Requirements
295
+
296
+ The database must be open.
297
+
298
+ @par Thread safety
299
+
300
+ Not thread safe. The caller is responsible for
301
+ ensuring that no other member functions are
302
+ called concurrently.
303
+
304
+ @param ec Set to the error, if any occurred.
305
+ */
306
+ void
307
+ close(error_code& ec);
308
+
309
+ /** Open a database.
310
+
311
+ The database identified by the specified data, key, and
312
+ log file paths is opened. If a log file is present, the
313
+ recovery mechanism is invoked to restore database integrity
314
+ before the function returns.
315
+
316
+ @par Requirements
317
+
318
+ The database must be not be open.
319
+
320
+ @par Thread safety
321
+
322
+ Not thread safe. The caller is responsible for
323
+ ensuring that no other member functions are
324
+ called concurrently.
325
+
326
+ @param dat_path The path to the data file.
327
+
328
+ @param key_path The path to the key file.
329
+
330
+ @param log_path The path to the log file.
331
+
332
+ @param ec Set to the error, if any occurred.
333
+
334
+ @param args Optional arguments passed to @b File constructors.
335
+
336
+ */
337
+ template<class... Args>
338
+ void
339
+ open(
340
+ path_type const& dat_path,
341
+ path_type const& key_path,
342
+ path_type const& log_path,
343
+ error_code& ec,
344
+ Args&&... args);
345
+
346
+ /** Fetch a value.
347
+
348
+ The function checks the database for the specified
349
+ key, and invokes the callback if it is found. If
350
+ the key is not found, `ec` is set to @ref error::key_not_found.
351
+ If any other errors occur, `ec` is set to the
352
+ corresponding error.
353
+
354
+ @par Requirements
355
+
356
+ The database must be open.
357
+
358
+ @par Thread safety
359
+
360
+ Safe to call concurrently with any function except
361
+ @ref close.
362
+
363
+ @note If the implementation encounters an error while
364
+ committing data to the database, this function will
365
+ immediately return with `ec` set to the error which
366
+ occurred. All subsequent calls to @ref fetch will
367
+ return the same error until the database is closed.
368
+
369
+ @param key A pointer to a memory buffer of at least
370
+ @ref key_size() bytes, containing the key to be searched
371
+ for.
372
+
373
+ @param callback A function which will be called with the
374
+ value data if the fetch is successful. The equivalent
375
+ signature must be:
376
+ @code
377
+ void callback(
378
+ void const* buffer, // A buffer holding the value
379
+ std::size_t size // The size of the value in bytes
380
+ );
381
+ @endcode
382
+ The buffer provided to the callback remains valid
383
+ until the callback returns, ownership is not transferred.
384
+
385
+ @param ec Set to the error, if any occurred.
386
+ */
387
+ template<class Callback>
388
+ void
389
+ fetch(void const* key, Callback && callback, error_code& ec);
390
+
391
+ /** Insert a value.
392
+
393
+ This function attempts to insert the specified key/value
394
+ pair into the database. If the key already exists,
395
+ `ec` is set to @ref error::key_exists. If an error
396
+ occurs, `ec` is set to the corresponding error.
397
+
398
+ @par Requirements
399
+
400
+ The database must be open.
401
+
402
+ @par Thread safety
403
+
404
+ Safe to call concurrently with any function except
405
+ @ref close.
406
+
407
+ @note If the implementation encounters an error while
408
+ committing data to the database, this function will
409
+ immediately return with `ec` set to the error which
410
+ occurred. All subsequent calls to @ref insert will
411
+ return the same error until the database is closed.
412
+
413
+ @param key A buffer holding the key to be inserted. The
414
+ size of the buffer should be at least the `key_size`
415
+ associated with the open database.
416
+
417
+ @param data A buffer holding the value to be inserted.
418
+
419
+ @param bytes The size of the buffer holding the value
420
+ data. This value must be greater than 0 and no more
421
+ than 0xffffffff.
422
+
423
+ @param ec Set to the error, if any occurred.
424
+ */
425
+ void
426
+ insert(void const* key, void const* data,
427
+ nsize_t bytes, error_code& ec);
428
+
429
+ private:
430
+ template<class Callback>
431
+ void
432
+ fetch(detail::nhash_t h, void const* key,
433
+ detail::bucket b, Callback && callback, error_code& ec);
434
+
435
+ bool
436
+ exists(detail::nhash_t h, void const* key,
437
+ detail::shared_lock_type* lock, detail::bucket b, error_code& ec);
438
+
439
+ void
440
+ split(detail::bucket& b1, detail::bucket& b2,
441
+ detail::bucket& tmp, nbuck_t n1, nbuck_t n2,
442
+ nbuck_t buckets, nbuck_t modulus,
443
+ detail::bulk_writer<File>& w, error_code& ec);
444
+
445
+ detail::bucket
446
+ load(nbuck_t n, detail::cache& c1,
447
+ detail::cache& c0, void* buf, error_code& ec);
448
+
449
+ void
450
+ commit(detail::unique_lock_type& m,
451
+ std::size_t& work, error_code& ec);
452
+
453
+ void
454
+ flush() override;
455
+ };
456
+
457
+ } // nudb
458
+
459
+ #include <nudb/impl/basic_store.ipp>
460
+
461
+ #endif
@@ -0,0 +1,205 @@
1
+ //
2
+ // Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
3
+ //
4
+ // Distributed under the Boost Software License, Version 1.0. (See accompanying
5
+ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
+ //
7
+
8
+ #ifndef NUDB_CONCEPTS_HPP
9
+ #define NUDB_CONCEPTS_HPP
10
+
11
+ #include <nudb/error.hpp>
12
+ #include <nudb/file.hpp>
13
+ #include <cstddef>
14
+ #include <cstdint>
15
+ #include <type_traits>
16
+
17
+ namespace nudb {
18
+
19
+ namespace detail {
20
+
21
+ template<class T>
22
+ class check_is_File
23
+ {
24
+ template<class U, class R =
25
+ std::is_convertible<decltype(
26
+ std::declval<U const>().is_open()),
27
+ bool>>
28
+ static R check1(int);
29
+ template<class>
30
+ static std::false_type check1(...);
31
+ using type1 = decltype(check1<T>(0));
32
+
33
+ template<class U, class R = decltype(
34
+ std::declval<U>().close(),
35
+ std::true_type{})>
36
+ static R check2(int);
37
+ template<class>
38
+ static std::false_type check2(...);
39
+ using type2 = decltype(check2<T>(0));
40
+
41
+ template<class U, class R = decltype(
42
+ std::declval<U>().create(
43
+ std::declval<file_mode>(),
44
+ std::declval<path_type>(),
45
+ std::declval<error_code&>()),
46
+ std::true_type{})>
47
+ static R check3(int);
48
+ template<class>
49
+ static std::false_type check3(...);
50
+ using type3 = decltype(check3<T>(0));
51
+
52
+ template<class U, class R = decltype(
53
+ std::declval<U>().open(
54
+ std::declval<file_mode>(),
55
+ std::declval<path_type>(),
56
+ std::declval<error_code&>()),
57
+ std::true_type{})>
58
+ static R check4(int);
59
+ template<class>
60
+ static std::false_type check4(...);
61
+ using type4 = decltype(check4<T>(0));
62
+
63
+ template<class U, class R = decltype(
64
+ U::erase(
65
+ std::declval<path_type>(),
66
+ std::declval<error_code&>()),
67
+ std::true_type{})>
68
+ static R check5(int);
69
+ template<class>
70
+ static std::false_type check5(...);
71
+ using type5 = decltype(check5<T>(0));
72
+
73
+ template<class U, class R =
74
+ std::is_convertible<decltype(
75
+ std::declval<U const>().size(
76
+ std::declval<error_code&>())),
77
+ std::uint64_t>>
78
+ static R check6(int);
79
+ template<class>
80
+ static std::false_type check6(...);
81
+ using type6 = decltype(check6<T>(0));
82
+
83
+ template<class U, class R = decltype(
84
+ std::declval<U>().read(
85
+ std::declval<std::uint64_t>(),
86
+ std::declval<void*>(),
87
+ std::declval<std::size_t>(),
88
+ std::declval<error_code&>()),
89
+ std::true_type{})>
90
+ static R check7(int);
91
+ template<class>
92
+ static std::false_type check7(...);
93
+ using type7 = decltype(check7<T>(0));
94
+
95
+ template<class U, class R = decltype(
96
+ std::declval<U>().write(
97
+ std::declval<std::uint64_t>(),
98
+ std::declval<void const*>(),
99
+ std::declval<std::size_t>(),
100
+ std::declval<error_code&>()),
101
+ std::true_type{})>
102
+ static R check8(int);
103
+ template<class>
104
+ static std::false_type check8(...);
105
+ using type8 = decltype(check8<T>(0));
106
+
107
+ template<class U, class R = decltype(
108
+ std::declval<U>().sync(
109
+ std::declval<error_code&>()),
110
+ std::true_type{})>
111
+ static R check9(int);
112
+ template<class>
113
+ static std::false_type check9(...);
114
+ using type9 = decltype(check9<T>(0));
115
+
116
+ template<class U, class R = decltype(
117
+ std::declval<U>().trunc(
118
+ std::declval<std::uint64_t>(),
119
+ std::declval<error_code&>()),
120
+ std::true_type{})>
121
+ static R check10(int);
122
+ template<class>
123
+ static std::false_type check10(...);
124
+ using type10 = decltype(check10<T>(0));
125
+
126
+ public:
127
+ using type = std::integral_constant<bool,
128
+ std::is_move_constructible<T>::value &&
129
+ type1::value && type2::value && type3::value &&
130
+ type4::value && type5::value && type6::value &&
131
+ type7::value && type8::value && type9::value &&
132
+ type10::value
133
+ >;
134
+ };
135
+
136
+ template<class T>
137
+ class check_is_Hasher
138
+ {
139
+ template<class U, class R =
140
+ std::is_constructible<U, std::uint64_t>>
141
+ static R check1(int);
142
+ template<class>
143
+ static std::false_type check1(...);
144
+ using type1 = decltype(check1<T>(0));
145
+
146
+ template<class U, class R =
147
+ std::is_convertible<decltype(
148
+ std::declval<U const>().operator()(
149
+ std::declval<void const*>(),
150
+ std::declval<std::size_t>())),
151
+ std::uint64_t>>
152
+ static R check2(int);
153
+ template<class>
154
+ static std::false_type check2(...);
155
+ using type2 = decltype(check2<T>(0));
156
+ public:
157
+ using type = std::integral_constant<bool,
158
+ type1::value && type2::value>;
159
+ };
160
+
161
+ template<class T>
162
+ class check_is_Progress
163
+ {
164
+ template<class U, class R = decltype(
165
+ std::declval<U>().operator()(
166
+ std::declval<std::uint64_t>(),
167
+ std::declval<std::uint64_t>()),
168
+ std::true_type{})>
169
+ static R check1(int);
170
+ template<class>
171
+ static std::false_type check1(...);
172
+ public:
173
+ using type = decltype(check1<T>(0));
174
+ };
175
+
176
+ } // detail
177
+
178
+ /// Determine if `T` meets the requirements of @b `File`
179
+ template<class T>
180
+ #if GENERATING_DOCS
181
+ struct is_File : std::integral_constant<bool, ...>{};
182
+ #else
183
+ using is_File = typename detail::check_is_File<T>::type;
184
+ #endif
185
+
186
+
187
+ /// Determine if `T` meets the requirements of @b `Hasher`
188
+ template<class T>
189
+ #if GENERATING_DOCS
190
+ struct is_Hasher : std::integral_constant<bool, ...>{};
191
+ #else
192
+ using is_Hasher = typename detail::check_is_Hasher<T>::type;
193
+ #endif
194
+
195
+ /// Determine if `T` meets the requirements of @b `Progress`
196
+ template<class T>
197
+ #if GENERATING_DOCS
198
+ struct is_Progress : std::integral_constant<bool, ...>{};
199
+ #else
200
+ using is_Progress = typename detail::check_is_Progress<T>::type;
201
+ #endif
202
+
203
+ } // nudb
204
+
205
+ #endif