19
19
#include < string_view>
20
20
#include < type_traits>
21
21
#include < utility>
22
-
23
22
#include < vector>
24
23
25
24
namespace clang {
@@ -48,32 +47,51 @@ enum class Kind
48
47
//
49
48
// ------------------------------------------------
50
49
51
- /* * A type-erased object or array implementation .
50
+ /* * Reference-counting base class for dynamic types .
52
51
*/
53
52
class MRDOX_DECL
54
53
Any
55
54
{
56
55
std::atomic<std::size_t > mutable refs_ = 1 ;
57
56
58
57
protected:
58
+ /* * Destructor.
59
+ */
60
+ virtual ~Any () = 0 ;
61
+
62
+ /* * Constructor.
63
+ */
59
64
Any () noexcept ;
65
+
66
+ /* * Constructor.
67
+
68
+ The caller will have exclusive ownership
69
+ immediately after construction is complete.
70
+ */
60
71
Any (Any const &) noexcept ;
61
72
62
73
public:
63
- virtual ~Any () = 0 ;
64
-
74
+ /* * Return a pointer with shared ownership.
75
+ */
65
76
Any* addref () noexcept
66
77
{
67
78
++refs_;
68
79
return this ;
69
80
}
70
81
82
+ /* * Return a pointer with shared ownership.
83
+ */
71
84
Any const * addref () const noexcept
72
85
{
73
86
++refs_;
74
87
return this ;
75
88
}
76
89
90
+ /* * Release shared ownership.
91
+
92
+ If this is the last remaining owner,
93
+ then this will be deleted.
94
+ */
77
95
void release () const noexcept
78
96
{
79
97
if (--refs_ > 0 )
@@ -92,16 +110,16 @@ auto create(Args&&... args);
92
110
//
93
111
// ------------------------------------------------
94
112
95
- /* * A pointer container for object or array .
113
+ /* * A pointer container for dynamic objects .
96
114
*/
97
- template <class T = Any>
98
- requires std::convertible_to<T*, Any*>
115
+ template <class T >
99
116
class Pointer
100
117
{
101
118
Any* any_;
102
119
120
+ static_assert (std::derived_from<T, Any>);
121
+
103
122
template <class U >
104
- requires std::convertible_to<U*, Any*>
105
123
friend class Pointer ;
106
124
107
125
explicit
@@ -217,27 +235,102 @@ using ArrayPtr = Pointer<Array>;
217
235
class MRDOX_DECL
218
236
Object : public Any
219
237
{
220
- Object (Object const &);
238
+ protected:
239
+ /* * Constructor.
240
+
241
+ The newly constructed object will retain
242
+ a copy of the list of values in `other`.
243
+ */
244
+ Object (Object const & other);
221
245
222
246
public:
247
+ /* * The type of an element in this container.
248
+ */
223
249
using value_type = std::pair<std::string, Value>;
250
+
251
+ /* * The underlying, iterable range used by this container.
252
+ */
224
253
using list_type = std::vector<value_type>;
225
254
255
+ /* * Constructor.
256
+
257
+ Default-constructed objects are empty.
258
+ */
226
259
Object () noexcept ;
260
+
261
+ /* * Constructor.
262
+
263
+ Upon construction, the object will retain
264
+ ownership of a shallow copy of the specified
265
+ list. In particular, dynamic objects will
266
+ be acquired with shared ownership.
267
+
268
+ @param list The initial list of values.
269
+ */
227
270
explicit Object (list_type list);
271
+
272
+ /* * Return an iterable range with the contents.
273
+ */
228
274
list_type const & list () const noexcept ;
275
+
276
+ /* * Add elements to the container.
277
+
278
+ No checking is performed to prevent
279
+ the insertion of duplicate keys.
280
+ */
229
281
void append (std::string_view key, Value value);
282
+
283
+ /* * Add elements to the container.
284
+
285
+ No checking is performed to prevent
286
+ the insertion of duplicate keys.
287
+ */
230
288
void append (std::initializer_list<value_type>);
289
+
290
+ /* * Return a deep copy of the container.
291
+
292
+ In particular, dynamic objects will be
293
+ deeply copied; changes to the copy are
294
+ not reflected in the original.
295
+ */
231
296
virtual Value copy () const ;
297
+
298
+ /* * Return true if the container is empty.
299
+ */
232
300
virtual bool empty () const noexcept ;
301
+
302
+ /* * Return the value for a given key.
303
+
304
+ If the key does not exist, a null value
305
+ is returned.
306
+
307
+ @return The value, or null.
308
+
309
+ @param key The key.
310
+ */
233
311
virtual Value get (std::string_view key) const ;
312
+
313
+ /* * Set or replace the value for a given key.
314
+
315
+ This function inserts a new key or changes
316
+ the value for the existing key if it is
317
+ already present.
318
+
319
+ @param key The key.
320
+
321
+ @param value The value to set.
322
+ */
234
323
virtual void set (std::string_view key, Value value);
324
+
325
+ // VFALCO DEPRECATED (for duktape)
235
326
virtual std::vector<std::string_view> props () const ;
236
327
237
328
private:
238
329
list_type list_;
239
330
};
240
331
332
+ /* * Alias for a pointer to an Object.
333
+ */
241
334
using ObjectPtr = Pointer<Object>;
242
335
243
336
/* * Return a new object with a given list of properties.
@@ -260,14 +353,26 @@ class MRDOX_DECL
260
353
{
261
354
std::atomic<Object*> mutable p_ = nullptr ;
262
355
356
+ /* * Return the object.
357
+ */
263
358
virtual ObjectPtr construct () const = 0;
264
359
265
360
public:
266
- LazyObject () noexcept ;
361
+ /* * Destructor.
362
+ */
267
363
~LazyObject () noexcept ;
364
+
365
+ /* * Constructor.
366
+ */
367
+ LazyObject () noexcept ;
368
+
369
+ /* * Return the object.
370
+ */
268
371
ObjectPtr get () const ;
269
372
};
270
373
374
+ /* * Alias for a pointer to a LazyObject.
375
+ */
271
376
using LazyObjectPtr = Pointer<LazyObject>;
272
377
273
378
// ------------------------------------------------
@@ -368,12 +473,32 @@ class MRDOX_DECL
368
473
*/
369
474
Value copy () const ;
370
475
476
+ /* * Return the type of value contained.|
477
+ */
371
478
dom::Kind kind () const noexcept ;
479
+
480
+ /* * Return true if this is null.
481
+ */
372
482
bool isNull () const noexcept { return kind_ == Kind::Null; }
483
+
484
+ /* * Return true if this is a boolean.
485
+ */
373
486
bool isBool () const noexcept { return kind_ == Kind::Boolean; }
487
+
488
+ /* * Return true if this is an integer.
489
+ */
374
490
bool isInteger () const noexcept { return kind_ == Kind::Integer; }
491
+
492
+ /* * Return true if this is a string.
493
+ */
375
494
bool isString () const noexcept { return kind_ == Kind::String; }
495
+
496
+ /* * Return true if this is an array.
497
+ */
376
498
bool isArray () const noexcept { return kind_ == Kind::Array; }
499
+
500
+ /* * Return true if this is an object.
501
+ */
377
502
bool isObject () const noexcept
378
503
{
379
504
return
@@ -408,19 +533,33 @@ class MRDOX_DECL
408
533
return arr_;
409
534
}
410
535
411
- ObjectPtr getObject () const noexcept ;
536
+ /* * Return the object if this is an object.
412
537
413
- void swap (Value& other) noexcept ;
538
+ @throw Error `! isObject()`
539
+ */
540
+ ObjectPtr
541
+ getObject () const ;
542
+
543
+ /* * Swap two values.
544
+ */
545
+ void
546
+ swap (Value& other) noexcept ;
414
547
415
- friend void swap (Value& v0, Value& v1) noexcept
548
+ /* * Swap two values.
549
+ */
550
+ friend
551
+ void
552
+ swap (Value& v0, Value& v1) noexcept
416
553
{
417
554
v0.swap (v1);
418
555
}
419
556
};
420
557
558
+ /* * Return a non-empty string, or a null.
559
+ */
421
560
inline
422
561
Value
423
- nonEmptyString (
562
+ stringOrNull (
424
563
std::string_view s)
425
564
{
426
565
if (! s.empty ())
0 commit comments