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.
- checksums.yaml +7 -0
- data/.yardopts +1 -0
- data/LICENSE.txt +22 -0
- data/README.md +26 -0
- data/examples/example.rb +39 -0
- data/ext/rudb/NuDB/include/nudb/CMakeLists.txt +104 -0
- data/ext/rudb/NuDB/include/nudb/_experimental/basic_seconds_clock.hpp +200 -0
- data/ext/rudb/NuDB/include/nudb/_experimental/chrono_util.hpp +58 -0
- data/ext/rudb/NuDB/include/nudb/_experimental/test/fail_file.hpp +343 -0
- data/ext/rudb/NuDB/include/nudb/_experimental/test/temp_dir.hpp +73 -0
- data/ext/rudb/NuDB/include/nudb/_experimental/test/test_store.hpp +451 -0
- data/ext/rudb/NuDB/include/nudb/_experimental/test/xor_shift_engine.hpp +105 -0
- data/ext/rudb/NuDB/include/nudb/_experimental/util.hpp +288 -0
- data/ext/rudb/NuDB/include/nudb/basic_store.hpp +461 -0
- data/ext/rudb/NuDB/include/nudb/concepts.hpp +205 -0
- data/ext/rudb/NuDB/include/nudb/context.hpp +144 -0
- data/ext/rudb/NuDB/include/nudb/create.hpp +117 -0
- data/ext/rudb/NuDB/include/nudb/detail/arena.hpp +296 -0
- data/ext/rudb/NuDB/include/nudb/detail/bucket.hpp +473 -0
- data/ext/rudb/NuDB/include/nudb/detail/buffer.hpp +86 -0
- data/ext/rudb/NuDB/include/nudb/detail/bulkio.hpp +196 -0
- data/ext/rudb/NuDB/include/nudb/detail/cache.hpp +236 -0
- data/ext/rudb/NuDB/include/nudb/detail/endian.hpp +93 -0
- data/ext/rudb/NuDB/include/nudb/detail/field.hpp +265 -0
- data/ext/rudb/NuDB/include/nudb/detail/format.hpp +630 -0
- data/ext/rudb/NuDB/include/nudb/detail/gentex.hpp +259 -0
- data/ext/rudb/NuDB/include/nudb/detail/mutex.hpp +26 -0
- data/ext/rudb/NuDB/include/nudb/detail/pool.hpp +243 -0
- data/ext/rudb/NuDB/include/nudb/detail/store_base.hpp +45 -0
- data/ext/rudb/NuDB/include/nudb/detail/stream.hpp +149 -0
- data/ext/rudb/NuDB/include/nudb/detail/xxhash.hpp +328 -0
- data/ext/rudb/NuDB/include/nudb/error.hpp +257 -0
- data/ext/rudb/NuDB/include/nudb/file.hpp +55 -0
- data/ext/rudb/NuDB/include/nudb/impl/basic_store.ipp +785 -0
- data/ext/rudb/NuDB/include/nudb/impl/context.ipp +241 -0
- data/ext/rudb/NuDB/include/nudb/impl/create.ipp +163 -0
- data/ext/rudb/NuDB/include/nudb/impl/error.ipp +175 -0
- data/ext/rudb/NuDB/include/nudb/impl/posix_file.ipp +248 -0
- data/ext/rudb/NuDB/include/nudb/impl/recover.ipp +209 -0
- data/ext/rudb/NuDB/include/nudb/impl/rekey.ipp +248 -0
- data/ext/rudb/NuDB/include/nudb/impl/verify.ipp +634 -0
- data/ext/rudb/NuDB/include/nudb/impl/visit.ipp +96 -0
- data/ext/rudb/NuDB/include/nudb/impl/win32_file.ipp +264 -0
- data/ext/rudb/NuDB/include/nudb/native_file.hpp +76 -0
- data/ext/rudb/NuDB/include/nudb/nudb.hpp +27 -0
- data/ext/rudb/NuDB/include/nudb/posix_file.hpp +228 -0
- data/ext/rudb/NuDB/include/nudb/progress.hpp +32 -0
- data/ext/rudb/NuDB/include/nudb/recover.hpp +73 -0
- data/ext/rudb/NuDB/include/nudb/rekey.hpp +110 -0
- data/ext/rudb/NuDB/include/nudb/store.hpp +27 -0
- data/ext/rudb/NuDB/include/nudb/type_traits.hpp +63 -0
- data/ext/rudb/NuDB/include/nudb/verify.hpp +200 -0
- data/ext/rudb/NuDB/include/nudb/version.hpp +21 -0
- data/ext/rudb/NuDB/include/nudb/visit.hpp +63 -0
- data/ext/rudb/NuDB/include/nudb/win32_file.hpp +246 -0
- data/ext/rudb/NuDB/include/nudb/xxhasher.hpp +45 -0
- data/ext/rudb/extconf.rb +12 -0
- data/ext/rudb/rudb.cpp +234 -0
- data/lib/rudb/version.rb +3 -0
- data/lib/rudb.rb +1 -0
- 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
|