nlib
MpObject.h
Go to the documentation of this file.
1 
2 /*--------------------------------------------------------------------------------*
3  Project: CrossRoad
4  Copyright (C)Nintendo All rights reserved.
5 
6  These coded instructions, statements, and computer programs contain proprietary
7  information of Nintendo and/or its licensed developers and are protected by
8  national and international copyright laws. They may not be disclosed to third
9  parties or copied or duplicated in any form, in whole or in part, without the
10  prior written consent of Nintendo.
11 
12  The content herein is highly confidential and should be handled accordingly.
13  *--------------------------------------------------------------------------------*/
14 
15 #pragma once
16 #ifndef INCLUDE_NN_NLIB_MSGPACK_MPOBJECT_H_
17 #define INCLUDE_NN_NLIB_MSGPACK_MPOBJECT_H_
18 
19 #include <map>
20 #include <utility>
21 #include <vector>
22 #include <string>
23 #include <iterator>
24 
25 #include "nn/nlib/Config.h"
26 #include "nn/nlib/Swap.h"
27 #include "nn/nlib/Cstring.h"
28 #include "nn/nlib/Nlist.h"
29 
30 #ifdef __cpp_rvalue_references
31 #include <array>
32 #include <unordered_map>
33 #include <tuple>
34 #endif
35 
36 #if defined(_MSC_VER) && defined(nx_msgpack_EXPORTS)
37 #undef NLIB_VIS_PUBLIC
38 #define NLIB_VIS_PUBLIC NLIB_WINEXPORT
39 #endif
40 
41 NLIB_NAMESPACE_BEGIN
42 namespace msgpack {
43 
44 class MpObject;
45 
46 template<class T>
47 errno_t Box(MpObject* obj, const T& v);
48 
49 template<class T>
50 errno_t Unbox(const MpObject* obj, T* v);
51 
52 struct nil {};
53 
54 template<class T>
55 inline bool operator==(const nil& lhs, const T& rhs) NLIB_NOEXCEPT {
56  NLIB_UNUSED(lhs);
57  NLIB_UNUSED(rhs);
58  return false;
59 }
60 template<class T>
61 inline bool operator==(const T& lhs, const nil& rhs) NLIB_NOEXCEPT {
62  NLIB_UNUSED(lhs);
63  NLIB_UNUSED(rhs);
64  return false;
65 }
66 inline bool operator==(const nil& lhs, const nil& rhs) NLIB_NOEXCEPT {
67  NLIB_UNUSED(lhs);
68  NLIB_UNUSED(rhs);
69  return true;
70 }
71 template<class T>
72 inline bool operator!=(const nil& rhs, const T& lhs) NLIB_NOEXCEPT {
73  NLIB_UNUSED(lhs);
74  NLIB_UNUSED(rhs);
75  return true;
76 }
77 template<class T>
78 inline bool operator!=(const T& rhs, const nil& lhs) NLIB_NOEXCEPT {
79  NLIB_UNUSED(lhs);
80  NLIB_UNUSED(rhs);
81  return true;
82 }
83 inline bool operator!=(const nil& rhs, const nil& lhs) NLIB_NOEXCEPT {
84  NLIB_UNUSED(lhs);
85  NLIB_UNUSED(rhs);
86  return false;
87 }
88 
89 struct MpObjectKv;
90 class MpObjectAsArray;
91 class MpObjectAsMap;
92 class MpObjectAsString;
93 class MpObjectAsBinary;
94 class MpObjectAsExt;
95 
97  private:
98  union UnionType {
99  uint64_t u64;
100  int64_t i64;
101  float f32;
102  double f64;
103  Nlist<MpObject>* ary;
104  Nlist<MpObjectKv>* mp;
105  nlib_utf8_t* str;
106  void* binary;
107  };
108 
109  public:
110  static bool IsJsonPointer(const nlib_utf8_t* first, const nlib_utf8_t* last) NLIB_NOEXCEPT;
111  static bool IsJsonPointer(const nlib_utf8_t* str) NLIB_NOEXCEPT {
112  return IsJsonPointer(str, str + nlib_strlen(str));
113  }
114  static errno_t ResolveJsonPointer(MpObject** result, MpObject* root,
115  const nlib_utf8_t* json_pointer) NLIB_NOEXCEPT;
116  static errno_t DigByJsonPointer(MpObject** result, MpObject* root,
117  const nlib_utf8_t* json_pointer) NLIB_NOEXCEPT;
118  static errno_t RemoveByJsonPointer(MpObjectKv* removed, MpObject* root,
119  const nlib_utf8_t* json_pointer) NLIB_NOEXCEPT;
120 
121  public:
122  MpObjectAsArray AsArray() NLIB_NOEXCEPT;
123  const MpObjectAsArray AsArray() const NLIB_NOEXCEPT;
125  const MpObjectAsMap AsMap() const NLIB_NOEXCEPT;
126  MpObjectAsString AsString() NLIB_NOEXCEPT;
127  const MpObjectAsString AsString() const NLIB_NOEXCEPT;
128  MpObjectAsBinary AsBinary() NLIB_NOEXCEPT;
129  const MpObjectAsBinary AsBinary() const NLIB_NOEXCEPT;
131  const MpObjectAsExt AsExt() const NLIB_NOEXCEPT;
132 
133  MpObject* GetArrayItem(size_t n) NLIB_NOEXCEPT;
134  const MpObject* GetArrayItem(size_t n) const NLIB_NOEXCEPT;
135  MpObject& operator[](size_t n) {
136  NLIB_ASSERT(this->IsArray());
137  NLIB_ASSERT(n < size_);
138  return (*via_.ary)[n];
139  }
140  const MpObject& operator[](size_t n) const {
141  NLIB_ASSERT(this->IsArray());
142  NLIB_ASSERT(n < size_);
143  return (*via_.ary)[n];
144  }
145  const MpObject* GetMapItem(const nlib_utf8_t* str) const NLIB_NOEXCEPT;
146  MpObject* GetMapItem(const nlib_utf8_t* str) NLIB_NOEXCEPT;
147  template<size_t N>
148  MpObject* GetMapItem(const nlib_utf8_t (&str)[N]) NLIB_NOEXCEPT {
149  return GetMapItem(&str[0]);
150  }
151  template<size_t N>
152  const MpObject* GetMapItem(const nlib_utf8_t (&str)[N]) const NLIB_NOEXCEPT {
153  return GetMapItem(&str[0]);
154  }
155  template<class STDSTRING>
156  const MpObject* GetMapItem(const STDSTRING& str) const NLIB_NOEXCEPT {
157  return GetMapItem(&str[0], str.size());
158  }
159  template<class STDSTRING>
160  MpObject* GetMapItem(const STDSTRING& str) NLIB_NOEXCEPT {
161  return GetMapItem(&str[0], str.size());
162  }
163  errno_t Resize(uint32_t n);
164  MpObject* AppendArrayItem() NLIB_NOEXCEPT;
165  MpObject* InsertArrayItem(size_t n) NLIB_NOEXCEPT;
166  MpObjectKv* AppendMapItem() NLIB_NOEXCEPT;
167  NLIB_OVERRIDE_NEW;
168 
169  public:
170  MpObject() NLIB_NOEXCEPT : type_(kNil) {} // only do minimum memory access
171  ~MpObject() NLIB_NOEXCEPT { ReleaseIfNeeded(); }
172 #ifdef __cpp_rvalue_references
174  nlib_memcpy(this, sizeof(*this), &rhs, sizeof(rhs));
175  rhs.type_ = kNil;
176  }
178  ReleaseIfNeeded();
179  nlib_memcpy(this, sizeof(*this), &rhs, sizeof(rhs));
180  rhs.type_ = kNil;
181  return *this;
182  }
183 #endif
185  nlib_memcpy(this, sizeof(*this), &rhs, sizeof(rhs));
186  rhs.type_ = kNil;
187  }
189  ReleaseIfNeeded();
190  nlib_memcpy(this, sizeof(*this), &rhs, sizeof(rhs));
191  rhs.type_ = kNil;
192  return *this;
193  }
194 
195  // NOTE: implicit call was error in gcc or clang....
196  template<class T>
197  MpObject(const T& x) { // no explicit
198  MyBox<T, typename IsIntegral<T>::type, typename IsSigned<T>::type>::Construct(this, x);
199  }
200  errno_t GetArrayItem(size_t n, MpObject** obj) NLIB_NOEXCEPT NLIB_NONNULL;
201  errno_t GetArrayItem(size_t n, const MpObject** obj) const NLIB_NOEXCEPT NLIB_NONNULL;
202  errno_t GetMapItem(size_t n, MpObjectKv** obj) NLIB_NOEXCEPT NLIB_NONNULL;
203  errno_t GetMapItem(size_t n, const MpObjectKv** obj) const NLIB_NOEXCEPT NLIB_NONNULL;
204  errno_t
206  const MpObjectKv* kv;
207  errno_t e = this->GetMapItem(str, n, &kv);
208  if (e != 0) return e;
209  *obj = const_cast<MpObjectKv*>(kv);
210  return 0;
211  }
212  errno_t GetMapItem(const nlib_utf8_t* str, size_t n,
213  const MpObjectKv** obj) const NLIB_NOEXCEPT NLIB_NONNULL;
215  if (type_ == kString) return via_.str;
216  if (NLIB_LIKELY(type_ == kStringInline)) return reinterpret_cast<nlib_utf8_t*>(&raw14data_);
217  return nullptr;
218  }
219  errno_t RemoveArrayItem(size_t n, MpObject* obj) NLIB_NOEXCEPT;
220  errno_t RemoveMapItem(size_t n, MpObjectKv* kv) NLIB_NOEXCEPT;
221  errno_t RemoveMapItem(const nlib_utf8_t* key, MpObjectKv* kv) NLIB_NOEXCEPT;
222  template<class STDSTRING>
223  errno_t RemoveMapItem(const STDSTRING& str, MpObjectKv* kv) NLIB_NOEXCEPT {
224  return RemoveMapItem(str.c_str(), kv);
225  }
226 
228  return const_cast<MpObject*>(this)->GetString();
229  }
230  void* GetBinary(uint32_t* n) NLIB_NOEXCEPT;
231  const void* GetBinary(uint32_t* n) const NLIB_NOEXCEPT {
232  return const_cast<MpObject*>(this)->GetBinary(n);
233  }
234  void* GetExt(int8_t* tp, uint32_t* n) NLIB_NOEXCEPT;
235  const void* GetExt(int8_t* tp, uint32_t* n) const NLIB_NOEXCEPT {
236  return const_cast<MpObject*>(this)->GetExt(tp, n);
237  }
238 
239  // I/F which returns std::pair, std::tuple
240 #ifdef __cpp_rvalue_references
241  std::tuple<errno_t, const nlib_byte_t*, uint32_t> GetBinary() const NLIB_NOEXCEPT;
242  std::tuple<errno_t, int8_t, const nlib_byte_t*, uint32_t> GetExt() const NLIB_NOEXCEPT;
243  std::pair<errno_t, MpObject> RemoveArrayItem(size_t n) NLIB_NOEXCEPT {
244  std::pair<errno_t, MpObject> rval;
245  rval.first = RemoveArrayItem(n, &rval.second);
246  return rval;
247  }
248  std::pair<errno_t, MpObjectKv> RemoveMapItem(size_t n) NLIB_NOEXCEPT;
249 #endif
250  std::pair<errno_t, MpObjectKv*> GetMapItem(const nlib_utf8_t* str, size_t n) NLIB_NOEXCEPT {
251  MpObjectKv* kv;
252  return std::make_pair(GetMapItem(str, n, &kv), kv);
253  }
254  std::pair<errno_t, const MpObjectKv*>
255  GetMapItem(const nlib_utf8_t* str, size_t n) const NLIB_NOEXCEPT {
256  const MpObjectKv* kv;
257  return std::make_pair(GetMapItem(str, n, &kv), kv);
258  }
259  // std::pair<errno_t, int32_t> GetInt32, GetInt64, GetUint32, GetUint64,
260  // GetBoolean(), GetFloat(), GetDouble()
261  std::pair<errno_t, nlib_time> GetTimestamp() const NLIB_NOEXCEPT;
262 
263  errno_t InitArray(uint32_t n) NLIB_NOEXCEPT;
264  errno_t InitMap(uint32_t n) NLIB_NOEXCEPT;
265  errno_t InitString(uint32_t n) NLIB_NOEXCEPT;
266  errno_t InitString(const nlib_utf8_t* str, uint32_t n) NLIB_NOEXCEPT;
267  errno_t InitString(const nlib_utf8_t* str) NLIB_NOEXCEPT {
268  uint32_t n = static_cast<uint32_t>(nlib_strlen(str));
269  return InitString(str, n);
270  }
271  errno_t InitBinary(uint32_t n) NLIB_NOEXCEPT;
272  errno_t InitBinary(const void* p, uint32_t n) NLIB_NOEXCEPT;
273  errno_t InitExt(int8_t tp, uint32_t n) NLIB_NOEXCEPT;
274  errno_t InitExt(int8_t tp, const void* p, uint32_t n) NLIB_NOEXCEPT;
275  errno_t InitTimestamp(nlib_time t) NLIB_NOEXCEPT;
276 
277  public: // Box
279  template<uint32_t n>
280  errno_t Box(const nlib_utf8_t (&str)[n]) NLIB_NOEXCEPT;
281  template<class T, uint32_t n>
282  errno_t Box(const T (&vec)[n]);
283 #ifdef __cpp_rvalue_references
284  template<class T, size_t n>
285  errno_t Box(const std::array<T, n>& vec);
286 #endif
287  template<class T>
288  errno_t Box(const T& v) {
289  return MyBox<T, typename IsIntegral<T>::type, typename IsSigned<T>::type>::Box(this, v);
290  }
291  // Use BoxBinary(p, n) or Box(reinterpret_cast<const nlib_utf8_t*>(p)) instead
292  errno_t BoxBinary(const void* p, uint32_t n) NLIB_NOEXCEPT NLIB_NONNULL;
293  errno_t BoxExt(int8_t tp, const void* p, uint32_t n) NLIB_NOEXCEPT NLIB_NONNULL;
294 
295  public: // Unbox
296  template<class T, size_t n>
297  errno_t Unbox(T (&a)[n]) const {
298  return this->Unbox(&a[0], n);
299  }
300 #ifdef __cpp_rvalue_references
301  template<class T, size_t n>
302  errno_t Unbox(std::array<T, n>& a) {
303  return this->Unbox(reinterpret_cast<T*>(&*a.begin()), n);
304  }
305 #endif
306  template<size_t n>
308  return this->Unbox(&str[0], n);
309  }
310  template<class T>
311  errno_t Unbox(T* a, size_t n) const NLIB_NONNULL;
312  errno_t Unbox(nlib_utf8_t* str, size_t n) const NLIB_NOEXCEPT NLIB_NONNULL;
313  errno_t UnboxBinary(void* p, size_t n) const NLIB_NOEXCEPT NLIB_NONNULL;
314  errno_t UnboxExt(int8_t* tp, void* p, size_t n) const NLIB_NOEXCEPT NLIB_NONNULL;
315  template<class T>
316  errno_t Unbox(T v) const {
317  // T cannot be T* though v is only pointer type
318  // because of conflict against array types.
319  return MyBox<typename RemovePtr<T>::type,
320  typename IsIntegral<typename RemovePtr<T>::type>::type,
321  typename IsSigned<typename RemovePtr<T>::type>::type>::Unbox(this, v);
322  }
323 
324  public:
325  // You can use operator=() only for basic types(never fails).
326  // Use Box() otherwise.
327  template<class T>
328  MpObject& operator=(const T& x) {
329  MyBox<T, typename IsIntegral<T>::type, typename IsSigned<T>::type>::Assign(this, x);
330  return *this;
331  }
332 
333  MpObject* Clone() const NLIB_NOEXCEPT;
334 
335  public:
336  enum ObjectType {
337  kNil = 0,
348  kStringInline = 0x80 | kString,
349  kBinaryInline = 0x80 | kBinary,
350  kBooleanFalse = 0x00 | kBoolean,
351  kBooleanTrue = 0x80 | kBoolean
352  };
353  ObjectType GetType() const NLIB_NOEXCEPT { return static_cast<ObjectType>(type_ & 0x7F); }
354  uint32_t GetSize() const NLIB_NOEXCEPT {
355  if (type_ == kStringInline || type_ == kBinaryInline)
356  return raw14size_;
357  else
358  return size_;
359  }
360  bool IsNil() const NLIB_NOEXCEPT { return GetType() == kNil; }
361  bool IsBoolean() const NLIB_NOEXCEPT { return GetType() == kBoolean; }
362  bool IsInteger() const NLIB_NOEXCEPT {
363  ObjectType tp = GetType();
364  return tp == kUint64 || tp == kInt64;
365  }
366  bool IsFloat() const NLIB_NOEXCEPT { return GetType() == kFloat; }
367  bool IsDouble() const NLIB_NOEXCEPT { return GetType() == kDouble; }
368  bool IsString() const NLIB_NOEXCEPT { return GetType() == kString; }
369  bool IsBinary() const NLIB_NOEXCEPT { return GetType() == kBinary; }
370  bool IsExt() const NLIB_NOEXCEPT { return GetType() == kExt; }
371  bool IsArray() const NLIB_NOEXCEPT { return GetType() == kArray; }
372  bool IsMap() const NLIB_NOEXCEPT { return GetType() == kMap; }
373 
374  private:
375  errno_t Clone(MpObject* p) const NLIB_NOEXCEPT;
376  template<class T, class IS_INTEGRAL, class IS_SIGNED>
377  struct MyBox {
378  static errno_t Box(MpObject* This, const T& v) { return ::nlib_ns::msgpack::Box(This, v); }
379  static errno_t Unbox(const MpObject* This, T* v) {
380  if (!v) return EINVAL;
382  }
383  static void Assign(MpObject* This, const T& x);
384  static void Construct(MpObject* This, const T& x);
385  };
386  void ReleaseIfNeeded() NLIB_NOEXCEPT {
387  if (type_ >= kString && type_ <= kExt) ReleaseIfNeeded_();
388  }
389  void ReleaseIfNeeded_() NLIB_NOEXCEPT;
390 
391  private:
392  uint8_t type_;
393  uint8_t raw14size_;
394  uint8_t raw14data_;
395  // uint8_t _;
396  uint32_t size_;
397  UnionType via_;
399  friend NLIB_VIS_PUBLIC bool operator==(const MpObject& lhs, const MpObject& rhs);
400  friend class MpObjectAsArray;
401  friend class MpObjectAsMap;
402  friend class MpObjectAsString;
403  friend class MpObjectAsBinary;
404  friend class MpObjectAsExt;
405 };
406 
410 
411  public:
414 #ifdef __cpp_rvalue_references
415 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS
416  MpObjectKv(MpObjectKv&& rhs) = default;
417  MpObjectKv& operator=(MpObjectKv&& rhs) = default;
418 #else
419  MpObjectKv(MpObjectKv&& rhs) NLIB_NOEXCEPT : first(std::move(rhs.first)),
420  second(std::move(rhs.second)) {}
421  MpObjectKv& operator=(MpObjectKv&& rhs) NLIB_NOEXCEPT {
422  first = std::move(rhs.first);
423  second = std::move(rhs.second);
424  return *this;
425  }
426 #endif
427 #endif
428  MpObjectKv(MpObjectKv& rhs, move_tag) NLIB_NOEXCEPT : first(rhs.first, move_tag()),
429  second(rhs.second, move_tag()) {}
431  first.assign(rhs.first, move_tag());
432  second.assign(rhs.second, move_tag());
433  return *this;
434  }
435 
436  private:
438 };
439 
441  public:
444  typedef MpObject& reference;
445  typedef const MpObject& const_reference;
446  typedef MpObject* pointer;
447  typedef const MpObject* const_pointer;
448 #if defined(_MSC_VER) && _MSC_VER == 1800
449  MpObjectAsArray(const MpObjectAsArray& rhs) NLIB_NOEXCEPT : obj_(rhs.obj_) {}
450  MpObjectAsArray& operator=(const MpObjectAsArray& rhs) NLIB_NOEXCEPT { obj_ = rhs.obj_; }
451 #endif
452  explicit MpObjectAsArray(MpObject& obj) NLIB_NOEXCEPT : obj_(obj) {
453  NLIB_ASSERT(obj.IsArray());
454  }
455  iterator begin() NLIB_NOEXCEPT { return obj_.via_.ary->begin(); }
456  iterator end() NLIB_NOEXCEPT { return obj_.via_.ary->end(); }
457  const_iterator begin() const NLIB_NOEXCEPT { return obj_.via_.ary->begin(); }
458  const_iterator end() const NLIB_NOEXCEPT { return obj_.via_.ary->end(); }
459  reference front() NLIB_NOEXCEPT { return obj_.via_.ary->front(); }
460  const_reference front() const NLIB_NOEXCEPT { return obj_.via_.ary->front(); }
461  reference back() NLIB_NOEXCEPT { return obj_.via_.ary->back(); }
462  const_reference back() const NLIB_NOEXCEPT { return obj_.via_.ary->back(); }
464  NLIB_ASSERT(n < GetSize());
465  return (*obj_.via_.ary)[n];
466  }
468  NLIB_ASSERT(n < GetSize());
469  return (*obj_.via_.ary)[n];
470  }
471  size_t GetSize() const NLIB_NOEXCEPT { return obj_.size_; }
473 #ifdef NLIB_64BIT
474  NLIB_ASSERT(n < 0x100000000ULL);
475 #endif
476  if (!(*obj_.via_.ary).resize(n)) return ENOMEM;
477  obj_.size_ = static_cast<uint32_t>(n);
478  return 0;
479  }
480 #ifdef __cpp_rvalue_references
482  MpObject* p = obj_.via_.ary->push_back(std::forward<MpObject>(rhs));
483  if (NLIB_UNLIKELY(!p)) return ENOMEM;
484  ++obj_.size_;
485  NLIB_ASSERT(obj_.size_ == obj_.via_.ary->size());
486  return 0;
487  }
488  errno_t Insert(iterator it, MpObject&& rhs) NLIB_NOEXCEPT;
490  if (NLIB_UNLIKELY(n > GetSize())) return ERANGE;
491  iterator it = begin();
492  it.Advance(n);
493  return Insert(it, std::move(rhs));
494  }
495  errno_t Erase(iterator it) NLIB_NOEXCEPT;
497  if (NLIB_UNLIKELY(n >= GetSize())) return ERANGE;
498  iterator it = begin();
499  it.Advance(n);
500  return Erase(it);
501  }
502 #endif
504  if (!obj_.via_.ary->pop_back()) {
505  return ENOENT;
506  }
507  --obj_.size_;
508  NLIB_ASSERT(obj_.size_ == obj_.via_.ary->size());
509  return 0;
510  }
511 
512  private:
513  MpObject& obj_;
514 };
515 inline MpObjectAsArray MpObject::AsArray() NLIB_NOEXCEPT {
516  return MpObjectAsArray(*this);
517 }
518 inline const MpObjectAsArray MpObject::AsArray() const NLIB_NOEXCEPT {
519  return MpObjectAsArray(const_cast<MpObject&>(*this));
520 }
521 inline MpObject* MpObject::GetArrayItem(size_t n) NLIB_NOEXCEPT {
522  if (NLIB_UNLIKELY(!IsArray())) return NULL;
523  MpObjectAsArray ar = AsArray();
524  if (NLIB_UNLIKELY(n >= ar.GetSize())) return nullptr;
525  return &ar[n];
526 }
527 inline const MpObject* MpObject::GetArrayItem(size_t n) const NLIB_NOEXCEPT {
528  if (NLIB_UNLIKELY(!IsArray())) return NULL;
529  const MpObjectAsArray ar = AsArray();
530  if (NLIB_UNLIKELY(n >= ar.GetSize())) return nullptr;
531  return &ar[n];
532 }
533 
535  public:
539  typedef const MpObjectKv& const_reference;
540  typedef MpObjectKv* pointer;
541  typedef const MpObjectKv* const_pointer;
542 #if defined(_MSC_VER) && _MSC_VER == 1800
543  MpObjectAsMap(const MpObjectAsMap& rhs) NLIB_NOEXCEPT : obj_(rhs.obj_) {}
544  MpObjectAsMap& operator=(const MpObjectAsMap& rhs) NLIB_NOEXCEPT { obj_ = rhs.obj_; }
545 #endif
546  explicit MpObjectAsMap(MpObject& obj) NLIB_NOEXCEPT : obj_(obj) { NLIB_ASSERT(obj.IsMap()); }
547  iterator begin() NLIB_NOEXCEPT { return obj_.via_.mp->begin(); }
548  iterator end() NLIB_NOEXCEPT { return obj_.via_.mp->end(); }
549  const_iterator begin() const NLIB_NOEXCEPT { return obj_.via_.mp->begin(); }
550  const_iterator end() const NLIB_NOEXCEPT { return obj_.via_.mp->end(); }
552  NLIB_ASSERT(n < GetSize());
553  return (*obj_.via_.mp)[n];
554  }
556  NLIB_ASSERT(n < GetSize());
557  return (*obj_.via_.mp)[n];
558  }
559  iterator GetByKey(const MpObject& key) NLIB_NOEXCEPT;
560  const_iterator GetByKey(const MpObject& key) const NLIB_NOEXCEPT;
561  template<class StringIterator>
562  iterator GetByKey(StringIterator first, StringIterator last) NLIB_NOEXCEPT;
563  template<class StringIterator>
564  const_iterator GetByKey(StringIterator first, StringIterator last) const NLIB_NOEXCEPT;
565  iterator GetByKey(const nlib_utf8_t* key) NLIB_NOEXCEPT;
566  const_iterator GetByKey(const nlib_utf8_t* key) const NLIB_NOEXCEPT;
567 
568  uint32_t GetSize() const NLIB_NOEXCEPT { return obj_.size_; }
570 #ifdef NLIB_64BIT
571  NLIB_ASSERT(n < 0x100000000ULL);
572 #endif
573  if (!(*obj_.via_.mp).resize(n)) return ENOMEM;
574  obj_.size_ = static_cast<uint32_t>(n);
575  return 0;
576  }
577 #ifdef __cpp_rvalue_references
579  MpObjectKv* p = obj_.via_.mp->push_back(std::forward<MpObjectKv>(rhs));
580  if (NLIB_UNLIKELY(!p)) return ENOMEM;
581  ++obj_.size_;
582  return 0;
583  }
585  MpObjectKv kv;
586  errno_t e = kv.first.InitString(key);
587  if (NLIB_UNLIKELY(e != 0)) return e;
588  kv.second = std::move(value);
589  return PushBack(std::move(kv));
590  }
591 #endif
593  if (!obj_.via_.mp->pop_back()) {
594  return ENOENT;
595  }
596  --obj_.size_;
597  return 0;
598  }
599 #ifdef __cpp_rvalue_references
600  errno_t Erase(iterator it) NLIB_NOEXCEPT;
602  if (NLIB_UNLIKELY(n >= GetSize())) return ERANGE;
603  iterator it = begin();
604  it.Advance(n);
605  return Erase(it);
606  }
607  errno_t Erase(const nlib_utf8_t* key) NLIB_NOEXCEPT;
608 #endif
609 
610  private:
611  MpObject& obj_;
612 };
613 inline MpObjectAsMap MpObject::AsMap() NLIB_NOEXCEPT {
614  return MpObjectAsMap(*this);
615 }
616 inline const MpObjectAsMap MpObject::AsMap() const NLIB_NOEXCEPT {
617  return MpObjectAsMap(const_cast<MpObject&>(*this));
618 }
619 
621  public:
623  typedef const nlib_utf8_t* const_iterator;
624  typedef std::reverse_iterator<iterator> reverse_iterator;
625  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
627  typedef const nlib_utf8_t& const_reference;
628 #if defined(_MSC_VER) && _MSC_VER == 1800
629  MpObjectAsString(const MpObjectAsString& rhs) NLIB_NOEXCEPT : obj_(rhs.obj_) {}
630  MpObjectAsString& operator=(const MpObjectAsString& rhs) NLIB_NOEXCEPT { obj_ = rhs.obj_; }
631 #endif
632  explicit MpObjectAsString(MpObject& obj) NLIB_NOEXCEPT : obj_(obj) {
633  NLIB_ASSERT(obj.IsString());
634  }
635  iterator begin() NLIB_NOEXCEPT { return ptr(); }
636  iterator end() NLIB_NOEXCEPT { return ptr() + GetSize(); }
637  const_iterator begin() const NLIB_NOEXCEPT { return ptr(); }
638  const_iterator end() const NLIB_NOEXCEPT { return ptr() + GetSize(); }
639  reverse_iterator rbegin() NLIB_NOEXCEPT { return std::reverse_iterator<iterator>(end()); }
640  reverse_iterator rend() NLIB_NOEXCEPT { return std::reverse_iterator<iterator>(begin()); }
642  return std::reverse_iterator<const_iterator>(end());
643  }
645  return std::reverse_iterator<const_iterator>(begin());
646  }
647 
648  reference operator[](size_t n) NLIB_NOEXCEPT { return *(begin() + n); }
649  const_reference operator[](size_t n) const NLIB_NOEXCEPT { return *(begin() + n); }
651  NLIB_ASSERT(n < GetSize());
652  return *(begin() + n);
653  }
654  const_reference at(size_t n) const NLIB_NOEXCEPT {
655  NLIB_ASSERT(n < GetSize());
656  return *(begin() + n);
657  }
658 
659  uint32_t GetSize() const NLIB_NOEXCEPT {
660  return (obj_.type_ == MpObject::kStringInline) ? obj_.raw14size_ : obj_.size_;
661  }
662  size_t size() const NLIB_NOEXCEPT { return GetSize(); }
663  size_t length() const NLIB_NOEXCEPT { return GetSize(); }
664  size_t max_size() const NLIB_NOEXCEPT { return GetSize(); }
665  bool empty() const NLIB_NOEXCEPT { return GetSize() == 0; }
666 
667  const nlib_utf8_t* c_str() const NLIB_NOEXCEPT { return ptr(); }
668  const nlib_utf8_t* data() const NLIB_NOEXCEPT { return ptr(); }
669 
670  private:
671  const nlib_utf8_t* ptr() const NLIB_NOEXCEPT {
672  if (obj_.type_ == MpObject::kString) return obj_.via_.str;
673  NLIB_ASSERT(obj_.type_ == MpObject::kStringInline);
674  return reinterpret_cast<const nlib_utf8_t*>(&obj_.raw14data_);
675  }
676  nlib_utf8_t* ptr() NLIB_NOEXCEPT {
677  if (obj_.type_ == MpObject::kString) return obj_.via_.str;
678  NLIB_ASSERT(obj_.type_ == MpObject::kStringInline);
679  return reinterpret_cast<nlib_utf8_t*>(&obj_.raw14data_);
680  }
681 
682  private:
683  MpObject& obj_;
684 };
685 inline MpObjectAsString MpObject::AsString() NLIB_NOEXCEPT {
686  return MpObjectAsString(*this);
687 }
688 inline const MpObjectAsString MpObject::AsString() const NLIB_NOEXCEPT {
689  return MpObjectAsString(const_cast<MpObject&>(*this));
690 }
691 
693  public:
695  typedef const nlib_byte_t* const_iterator;
696  typedef std::reverse_iterator<iterator> reverse_iterator;
697  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
699  typedef const nlib_byte_t& const_reference;
700 
701 #if defined(_MSC_VER) && _MSC_VER == 1800
702  MpObjectAsBinary(const MpObjectAsBinary& rhs) NLIB_NOEXCEPT : obj_(rhs.obj_) {}
703  MpObjectAsBinary& operator=(const MpObjectAsBinary& rhs) NLIB_NOEXCEPT { obj_ = rhs.obj_; }
704 #endif
705  explicit MpObjectAsBinary(MpObject& obj) NLIB_NOEXCEPT : obj_(obj) {
706  NLIB_ASSERT(obj.IsBinary());
707  }
708  iterator begin() NLIB_NOEXCEPT { return ptr(); }
709  iterator end() NLIB_NOEXCEPT { return ptr() + GetSize(); }
710  const_iterator begin() const NLIB_NOEXCEPT { return ptr(); }
711  const_iterator end() const NLIB_NOEXCEPT { return ptr() + GetSize(); }
712  reverse_iterator rbegin() NLIB_NOEXCEPT { return std::reverse_iterator<iterator>(end()); }
713  reverse_iterator rend() NLIB_NOEXCEPT { return std::reverse_iterator<iterator>(begin()); }
715  return std::reverse_iterator<const_iterator>(end());
716  }
718  return std::reverse_iterator<const_iterator>(begin());
719  }
720  reference operator[](size_t n) NLIB_NOEXCEPT { return *(begin() + n); }
721  const_reference operator[](size_t n) const NLIB_NOEXCEPT { return *(begin() + n); }
722  uint32_t GetSize() const NLIB_NOEXCEPT {
723  return (obj_.type_ == MpObject::kBinaryInline) ? obj_.raw14size_ : obj_.size_;
724  }
725 
726  private:
727  const nlib_byte_t* ptr() const NLIB_NOEXCEPT {
728  if (obj_.type_ == MpObject::kBinary)
729  return static_cast<const nlib_byte_t*>(obj_.via_.binary);
730  NLIB_ASSERT(obj_.type_ == MpObject::kBinaryInline);
731  return reinterpret_cast<const nlib_byte_t*>(&obj_.raw14data_);
732  }
733  nlib_byte_t* ptr() NLIB_NOEXCEPT {
734  if (obj_.type_ == MpObject::kBinary) return static_cast<nlib_byte_t*>(obj_.via_.binary);
735  NLIB_ASSERT(obj_.type_ == MpObject::kBinaryInline);
736  return reinterpret_cast<nlib_byte_t*>(&obj_.raw14data_);
737  }
738 
739  private:
740  MpObject& obj_;
741 };
742 inline MpObjectAsBinary MpObject::AsBinary() NLIB_NOEXCEPT {
743  return MpObjectAsBinary(*this);
744 }
745 inline const MpObjectAsBinary MpObject::AsBinary() const NLIB_NOEXCEPT {
746  return MpObjectAsBinary(const_cast<MpObject&>(*this));
747 }
748 inline void* MpObject::GetBinary(uint32_t* n) NLIB_NOEXCEPT {
749  if (NLIB_UNLIKELY(!IsBinary())) return nullptr;
750  MpObjectAsBinary bin(*this);
751  *n = bin.GetSize();
752  return &*bin.begin();
753 }
754 #ifdef __cpp_rvalue_references
755 inline std::tuple<errno_t, const nlib_byte_t*, uint32_t> MpObject::GetBinary() const NLIB_NOEXCEPT {
756  if (NLIB_UNLIKELY(!IsBinary())) return std::make_tuple(EACCES, nullptr, 0);
757  MpObjectAsBinary bin = AsBinary();
758  return std::make_tuple(0, &*bin.begin(), bin.GetSize());
759 }
760 #endif
761 
763  public:
764 #if defined(_MSC_VER) && _MSC_VER == 1800
765  MpObjectAsExt(const MpObjectAsExt& rhs) NLIB_NOEXCEPT : obj_(rhs.obj_) {}
766  MpObjectAsExt& operator=(const MpObjectAsExt& rhs) NLIB_NOEXCEPT { obj_ = rhs.obj_; }
767 #endif
768  explicit MpObjectAsExt(MpObject& obj) NLIB_NOEXCEPT : obj_(obj) { NLIB_ASSERT(obj.IsExt()); }
769  void* GetExtData() NLIB_NOEXCEPT { return obj_.via_.binary; }
770  const void* GetExtData() const NLIB_NOEXCEPT { return obj_.via_.binary; }
771  int8_t GetExtType() const NLIB_NOEXCEPT { return static_cast<int8_t>(obj_.raw14data_); }
772  uint32_t GetSize() const NLIB_NOEXCEPT { return obj_.size_; }
773 
774  private:
775  MpObject& obj_;
776 };
777 inline MpObjectAsExt MpObject::AsExt() NLIB_NOEXCEPT {
778  return MpObjectAsExt(*this);
779 }
780 inline const MpObjectAsExt MpObject::AsExt() const NLIB_NOEXCEPT {
781  return MpObjectAsExt(const_cast<MpObject&>(*this));
782 }
783 inline void* MpObject::GetExt(int8_t* tp, uint32_t* n) NLIB_NOEXCEPT {
784  if (NLIB_UNLIKELY(!IsExt())) return nullptr;
785  MpObjectAsExt ext(*this);
786  *n = ext.GetSize();
787  *tp = ext.GetExtType();
788  return ext.GetExtData();
789 }
790 #ifdef __cpp_rvalue_references
791 inline std::tuple<errno_t, int8_t, const nlib_byte_t*, uint32_t>
792 MpObject::GetExt() const NLIB_NOEXCEPT {
793  if (NLIB_UNLIKELY(!IsExt())) return std::make_tuple(EACCES, static_cast<int8_t>(0), nullptr, 0);
794  MpObjectAsExt ext = AsExt();
795  return std::make_tuple(0, ext.GetExtType(), static_cast<const nlib_byte_t*>(ext.GetExtData()),
796  ext.GetSize());
797 }
798 #endif
799 
800 template<class StringIterator>
802 MpObjectAsMap::GetByKey(StringIterator first, StringIterator last) NLIB_NOEXCEPT {
803  MpObjectAsMap::iterator itend = end();
804  MpObjectAsMap::iterator it = begin();
805  for (; it != itend; ++it) {
806  if (!it->first.IsString()) continue;
807  uint32_t len = it->first.GetSize();
808  if (len != last - first) continue;
809  const nlib_utf8_t* k = it->first.GetString();
810  while (first != last) {
811  if (*k++ != *first++) break;
812  }
813  if (first == last) break;
814  }
815  return it;
816 }
817 template<class StringIterator>
819 MpObjectAsMap::GetByKey(StringIterator first, StringIterator last) const NLIB_NOEXCEPT {
820  MpObjectAsMap::const_iterator itend = end();
821  MpObjectAsMap::const_iterator it = begin();
822  for (; it != itend; ++it) {
823  if (!it->first.IsString()) continue;
824  uint32_t len = it->first.GetSize();
825  if (len != last - first) continue;
826  const nlib_utf8_t* k = it->first.GetString();
827  while (first != last) {
828  if (*k++ != *first++) break;
829  }
830  if (first == last) break;
831  }
832  return it;
833 }
834 
835 #ifdef __cpp_rvalue_references
836 inline std::pair<errno_t, MpObjectKv> MpObject::RemoveMapItem(size_t n) NLIB_NOEXCEPT {
837  std::pair<errno_t, MpObjectKv> rval;
838  rval.first = RemoveMapItem(n, &rval.second);
839  return rval;
840 }
841 #endif
842 
843 template<>
844 struct MpObject::MyBox<nil, FalseType, FalseType> {
845  static errno_t Box(MpObject* This, nil v) NLIB_NOEXCEPT {
846  NLIB_UNUSED(v);
847  This->ReleaseIfNeeded();
848  This->type_ = kNil;
849  return 0;
850  }
851  static void Assign(MpObject* This, nil x) NLIB_NOEXCEPT { This->Box(x); }
852  static void Construct(MpObject* This, nil) NLIB_NOEXCEPT { This->type_ = kNil; }
853 };
854 
855 template<>
856 struct MpObject::MyBox<bool, TrueType, FalseType> {
857  static errno_t Box(MpObject* This, bool v) NLIB_NOEXCEPT {
858  This->ReleaseIfNeeded();
859  This->type_ = v ? static_cast<uint8_t>(kBooleanTrue) : static_cast<uint8_t>(kBooleanFalse);
860  return 0;
861  }
862  static errno_t Unbox(const MpObject* This, bool* v) NLIB_NOEXCEPT {
863  if (This->type_ == kBooleanFalse) {
864  *v = false;
865  return 0;
866  } else if (NLIB_LIKELY(This->type_ == kBooleanTrue)) {
867  *v = true;
868  return 0;
869  }
870  *v = false; // to suppress warnings
871  return EACCES;
872  }
873  static void Assign(MpObject* This, bool x) NLIB_NOEXCEPT { This->Box(x); }
874  static void Construct(MpObject* This, bool x) NLIB_NOEXCEPT {
875  This->type_ = x ? static_cast<uint8_t>(kBooleanTrue) : static_cast<uint8_t>(kBooleanFalse);
876  }
877 };
878 
879 template<class T>
880 struct MpObject::MyBox<T, TrueType, TrueType> {
881  static errno_t Box(MpObject* This, T v) NLIB_NOEXCEPT {
882  This->ReleaseIfNeeded();
883  This->type_ = kInt64;
884  This->via_.i64 = v;
885  return 0;
886  }
887  static errno_t Unbox(const MpObject* This, T* v) NLIB_NOEXCEPT {
888  if (NLIB_UNLIKELY(!v)) return EINVAL;
889  if (This->type_ == kInt64) {
890  *v = static_cast<T>(This->via_.i64);
891  return 0;
892  } else if (NLIB_LIKELY(This->type_ == kUint64)) {
893  *v = static_cast<T>(This->via_.u64);
894  return 0;
895  }
896  *v = 0; // to suppress warnings
897  return EACCES;
898  }
899  static void Assign(MpObject* This, T x) NLIB_NOEXCEPT { This->Box(x); }
900  static void Construct(MpObject* This, T x) NLIB_NOEXCEPT {
901  This->type_ = kInt64;
902  This->via_.i64 = x;
903  }
904 };
905 
906 template<class T>
907 struct MpObject::MyBox<T, TrueType, FalseType> {
908  static errno_t Box(MpObject* This, T v) NLIB_NOEXCEPT {
909  This->ReleaseIfNeeded();
910  This->type_ = kUint64;
911  This->via_.u64 = v;
912  return 0;
913  }
914  static errno_t Unbox(const MpObject* This, T* v) NLIB_NOEXCEPT {
915  if (NLIB_UNLIKELY(!v)) return EINVAL;
916  if (This->type_ == kInt64) {
917  *v = static_cast<T>(This->via_.i64);
918  return 0;
919  } else if (NLIB_LIKELY(This->type_ == kUint64)) {
920  *v = static_cast<T>(This->via_.u64);
921  return 0;
922  }
923  *v = 0; // to suppress warnings
924  return EACCES;
925  }
926  static void Assign(MpObject* This, T x) NLIB_NOEXCEPT { This->Box(x); }
927  static void Construct(MpObject* This, T x) NLIB_NOEXCEPT {
928  This->type_ = kUint64;
929  This->via_.u64 = x;
930  }
931 };
932 
933 template<class TR1_WORKAROUND>
934 struct MpObject::MyBox<float, FalseType, TR1_WORKAROUND> {
935  static errno_t Box(MpObject* This, float v) NLIB_NOEXCEPT {
936  This->ReleaseIfNeeded();
937  This->type_ = kFloat;
938  This->via_.f32 = v;
939  return 0;
940  }
941  static errno_t Unbox(const MpObject* This, float* v) NLIB_NOEXCEPT {
942  if (NLIB_UNLIKELY(!v)) return EINVAL;
943  switch (This->type_) {
944  case kFloat:
945  *v = This->via_.f32;
946  break;
947  case kDouble:
948  *v = static_cast<float>(This->via_.f64);
949  break;
950  default:
951  *v = 0; // to suppress warnings
952  return EACCES;
953  }
954  return 0;
955  }
956  static void Assign(MpObject* This, float x) NLIB_NOEXCEPT { This->Box(x); }
957  static void Construct(MpObject* This, float x) NLIB_NOEXCEPT {
958  This->type_ = kFloat;
959  This->via_.f32 = x;
960  }
961 };
962 
963 template<class TR1_WORKAROUND>
964 struct MpObject::MyBox<double, FalseType, TR1_WORKAROUND> {
965  static errno_t Box(MpObject* This, double v) NLIB_NOEXCEPT {
966  This->ReleaseIfNeeded();
967  This->type_ = kDouble;
968  This->via_.f64 = v;
969  return 0;
970  }
971  static errno_t Unbox(const MpObject* This, double* v) NLIB_NOEXCEPT {
972  if (NLIB_UNLIKELY(!v)) return EINVAL;
973  switch (This->type_) {
974  case kFloat:
975  *v = This->via_.f32;
976  break;
977  case kDouble:
978  *v = This->via_.f64;
979  break;
980  default:
981  *v = 0; // to suppress warnings
982  return EACCES;
983  }
984  return 0;
985  }
986  static void Assign(MpObject* This, double x) NLIB_NOEXCEPT { This->Box(x); }
987  static void Construct(MpObject* This, double x) NLIB_NOEXCEPT {
988  This->type_ = kDouble;
989  This->via_.f64 = x;
990  }
991 };
992 
993 template<>
994 struct MpObject::MyBox<std::string, FalseType, FalseType> {
995  static errno_t Box(MpObject* This, const std::string& str) NLIB_NOEXCEPT {
996  uint32_t n = static_cast<uint32_t>(str.size());
997  ErrnoT e = This->InitString(n);
998  if (NLIB_UNLIKELY(e != 0)) return e;
999  nlib_memcpy(static_cast<void*>(This->GetString()), n, static_cast<const void*>(&str[0]), n);
1000  return 0;
1001  }
1002  static errno_t Unbox(const MpObject* This, std::string* str) NLIB_NOEXCEPT {
1003  if (NLIB_UNLIKELY(!str)) return EINVAL;
1004  if (NLIB_UNLIKELY(This->type_ != kString) && NLIB_UNLIKELY(This->type_ != kStringInline))
1005  return EACCES;
1006  const nlib_utf8_t* chr = This->GetString();
1007  NLIB_TRY { (*str).assign(chr, This->GetSize()); }
1008  NLIB_CATCH(std::bad_alloc&) { return ENOMEM; }
1009  return 0;
1010  }
1011 };
1012 
1013 template<class T, class ALLOC>
1014 struct MpObject::MyBox<std::vector<T, ALLOC>, FalseType, FalseType> {
1015  static errno_t Box(MpObject* This, const std::vector<T, ALLOC>& vec) {
1016  uint32_t n = static_cast<uint32_t>(vec.size());
1017  MpObject tmp;
1018  ErrnoT e = tmp.InitArray(n);
1019  if (NLIB_UNLIKELY(e != 0)) return e;
1020 
1021  for (uint32_t i = 0; i < n; ++i) {
1022  e = (*tmp.via_.ary)[i].Box(vec[i]);
1023  if (NLIB_UNLIKELY(e != 0)) return e;
1024  }
1025  This->assign(tmp, move_tag());
1026  return 0;
1027  }
1028  static errno_t Unbox(const MpObject* This, std::vector<T, ALLOC>* vec) {
1029  if (NLIB_UNLIKELY(!vec)) return EINVAL;
1030  if (NLIB_UNLIKELY(This->type_ != kArray)) return EACCES;
1031  NLIB_TRY { vec->resize(This->size_); }
1032  NLIB_CATCH(std::bad_alloc&) { return ENOMEM; }
1033  for (uint32_t i = 0; i < This->size_; ++i) {
1034  ErrnoT e = (*This->via_.ary)[i].Unbox(&(*vec)[i]);
1035  if (NLIB_UNLIKELY(e != 0)) return e; // *vec NOT RESET
1036  }
1037  return 0;
1038  }
1039 };
1040 
1041 template<class T, class ALLOC>
1042 struct MpObject::MyBox<Nlist<T, ALLOC>, FalseType, FalseType> {
1043  static errno_t Box(MpObject* This, const Nlist<T, ALLOC>& vec) {
1044  size_t n = vec.size();
1045  MpObject tmp;
1046  ErrnoT e = tmp.InitArray(static_cast<uint32_t>(n));
1047  if (NLIB_UNLIKELY(e != 0)) return e;
1048  typename Nlist<T, ALLOC>::const_iterator it = vec.begin();
1049  for (size_t i = 0; i < n; ++it, ++i) {
1050  e = (*tmp.via_.ary)[i].Box(*it);
1051  if (NLIB_UNLIKELY(e != 0)) return e;
1052  }
1053  This->assign(tmp, move_tag());
1054  return 0;
1055  }
1056  static errno_t Unbox(const MpObject* This, Nlist<T, ALLOC>* vec) {
1057  if (NLIB_UNLIKELY(!vec)) return EINVAL;
1058  if (NLIB_UNLIKELY(This->type_ != kArray)) return EACCES;
1059  vec->clear();
1060  if (NLIB_UNLIKELY(!vec->reserve(This->size_))) return ENOMEM;
1061  for (uint32_t i = 0; i < This->size_; ++i) {
1062  T* item = vec->push_back();
1063  ErrnoT e = (*This->via_.ary)[i].Unbox(item);
1064  if (NLIB_UNLIKELY(e != 0)) return e; // *vec NOT RESET
1065  }
1066  return 0;
1067  }
1068 };
1069 
1070 template<class T1, class T2>
1071 struct MpObject::MyBox<std::pair<T1, T2>, FalseType, FalseType> {
1072  static errno_t Box(MpObject* This, const std::pair<T1, T2>& p) {
1073  MpObject tmp;
1074  ErrnoT e = tmp.InitArray(2);
1075  if (NLIB_UNLIKELY(e != 0)) return e;
1076  e = (*tmp.via_.ary)[0].Box(p.first);
1077  if (NLIB_UNLIKELY(e != 0)) return e;
1078  e = (*tmp.via_.ary)[1].Box(p.second);
1079  if (NLIB_UNLIKELY(e != 0)) return e;
1080  This->assign(tmp, move_tag());
1081  return 0;
1082  }
1083  static errno_t Unbox(const MpObject* This, std::pair<T1, T2>* p) {
1084  if (NLIB_UNLIKELY(!p)) return EINVAL;
1085  if (NLIB_UNLIKELY(This->type_ != kArray)) return EACCES;
1086  if (NLIB_UNLIKELY(This->size_ != 2)) return EACCES;
1087  ErrnoT e;
1088  e = (*This->via_.ary)[0].Unbox(&p->first);
1089  if (NLIB_UNLIKELY(e != 0)) return e; // *p NOT RESET
1090  e = (*This->via_.ary)[1].Unbox(&p->second);
1091  if (NLIB_UNLIKELY(e != 0)) return e; // *p NOT RESET
1092  return 0;
1093  }
1094 };
1095 
1096 #if defined(__cpp_rvalue_references) && defined(__cpp_variadic_templates)
1097 template<class... Args>
1098 struct MpObject::MyBox<std::tuple<Args...>, FalseType, FalseType> {
1099  private:
1100  template<size_t N, class HEAD>
1101  static errno_t BoxHelper(MpObject* tmp, const HEAD& head) {
1102  return (*tmp->via_.ary)[N].Box(head);
1103  }
1104  template<size_t N, class HEAD, class... TAIL>
1105  static errno_t BoxHelper(MpObject* tmp, const HEAD& head, TAIL&... tail) {
1106  ErrnoT e = (*tmp->via_.ary)[N].Box(head);
1107  if (NLIB_UNLIKELY(e != 0)) return e;
1108  return BoxHelper<N + 1, TAIL...>(tmp, tail...);
1109  }
1110  template<size_t N, class HEAD>
1111  static errno_t UnboxHelper(const MpObject* This, HEAD& head) {
1112  return (*This->via_.ary)[N].Unbox(&head);
1113  }
1114  template<size_t N, class HEAD, class... TAIL>
1115  static errno_t UnboxHelper(const MpObject* This, HEAD& head, TAIL&... tail) {
1116  ErrnoT e = (*This->via_.ary)[N].Unbox(&head);
1117  if (NLIB_UNLIKELY(e != 0)) return e;
1118  return UnboxHelper<N + 1, TAIL...>(This, tail...);
1119  }
1120  template<int...>
1121  struct seq {};
1122  template<int N, int... S>
1123  struct gens : gens<N - 1, N - 1, S...> {};
1124  template<int... S>
1125  struct gens<0, S...> {
1126  typedef seq<S...> type;
1127  };
1128  template<int... S>
1129  static errno_t Box(MpObject* tmp, seq<S...>, const std::tuple<Args...>& p) {
1130  return BoxHelper<0>(tmp, std::get<S>(p)...);
1131  }
1132  template<int... S>
1133  static errno_t Unbox(const MpObject* This, seq<S...>, std::tuple<Args...>& p) {
1134  return UnboxHelper<0>(This, std::get<S>(p)...);
1135  }
1136 
1137  public:
1138  static errno_t Box(MpObject* This, const std::tuple<Args...>& p) {
1139  size_t count = std::tuple_size<std::tuple<Args...> >::value;
1140  MpObject tmp;
1141  ErrnoT e = tmp.InitArray(static_cast<uint32_t>(count));
1142  if (NLIB_UNLIKELY(e != 0)) return e;
1143  typedef typename gens<sizeof...(Args)>::type MySeq;
1144  e = Box(&tmp, MySeq(), p);
1145  if (NLIB_UNLIKELY(e != 0)) return e;
1146  This->assign(tmp, move_tag());
1147  return 0;
1148  }
1149  static errno_t Unbox(const MpObject* This, std::tuple<Args...>* p) {
1150  if (NLIB_UNLIKELY(!p)) return EINVAL;
1151  if (NLIB_UNLIKELY(This->type_ != kArray)) return EACCES;
1152  if (NLIB_UNLIKELY(This->size_ != std::tuple_size<std::tuple<Args...> >::value))
1153  return EACCES;
1154  typedef typename gens<sizeof...(Args)>::type MySeq;
1155  return Unbox(This, MySeq(), *p);
1156  }
1157 };
1158 #endif
1159 
1160 template<class K, class V, class Pr, class Alloc>
1161 struct MpObject::MyBox<std::map<K, V, Pr, Alloc>, FalseType, FalseType> {
1162  static errno_t Box(MpObject* This, const std::map<K, V, Pr, Alloc>& m) {
1163  typedef typename std::map<K, V, Pr, Alloc> maptype;
1164  uint32_t n = static_cast<uint32_t>(m.size());
1165  MpObject tmp;
1166  ErrnoT e = tmp.InitMap(n);
1167  if (NLIB_UNLIKELY(e != 0)) return e;
1168 
1169  typename maptype::const_iterator it;
1170  typename maptype::const_iterator it_end = m.end();
1171  uint32_t i;
1172  for (i = 0, it = m.begin(); it != it_end; ++it, ++i) {
1173  MpObjectKv& kv = (*tmp.via_.mp)[i];
1174  e = kv.first.Box(it->first);
1175  if (NLIB_UNLIKELY(e != 0)) return e;
1176  e = kv.second.Box(it->second);
1177  if (NLIB_UNLIKELY(e != 0)) return e;
1178  }
1179  This->assign(tmp, move_tag());
1180  return 0;
1181  }
1182  static errno_t Unbox(const MpObject* This, std::map<K, V, Pr, Alloc>* m) {
1183  if (NLIB_UNLIKELY(!m)) return EINVAL;
1184  if (NLIB_UNLIKELY(This->type_ != kMap)) return EACCES;
1185  m->clear();
1186  for (uint32_t i = 0; i < This->size_; ++i) {
1187  K key;
1188  V value;
1189  const MpObjectKv& kv = (*This->via_.mp)[i];
1190  ErrnoT e;
1191  e = kv.first.Unbox(&key);
1192  if (NLIB_UNLIKELY(e != 0)) return e; // *m NOT RESET
1193  e = kv.second.Unbox(&value);
1194  if (NLIB_UNLIKELY(e != 0)) return e; // *m NOT RESET
1195  NLIB_TRY { (*m)[NLIB_MOVE(key)] = NLIB_MOVE(value); }
1196  NLIB_CATCH(...) { return ENOMEM; }
1197  }
1198  return 0;
1199  }
1200 };
1201 
1202 #ifdef __cpp_rvalue_references
1203 template<class K, class V, class Hash, class Pr, class Alloc>
1204 struct MpObject::MyBox<std::unordered_map<K, V, Hash, Pr, Alloc>, FalseType, FalseType> {
1205  static errno_t Box(MpObject* This, const std::unordered_map<K, V, Hash, Pr, Alloc>& m) {
1206  typedef typename std::unordered_map<K, V, Hash, Pr, Alloc> maptype;
1207  uint32_t n = static_cast<uint32_t>(m.size());
1208  MpObject tmp;
1209  ErrnoT e = tmp.InitMap(n);
1210  if (NLIB_UNLIKELY(e != 0)) return e;
1211 
1212  typename maptype::const_iterator it;
1213  typename maptype::const_iterator it_end = m.end();
1214  uint32_t i;
1215  for (i = 0, it = m.begin(); it != it_end; ++it, ++i) {
1216  MpObjectKv& kv = (*tmp.via_.mp)[i];
1217  e = kv.first.Box(it->first);
1218  if (NLIB_UNLIKELY(e != 0)) return e;
1219  e = kv.second.Box(it->second);
1220  if (NLIB_UNLIKELY(e != 0)) return e;
1221  }
1222  This->assign(tmp, move_tag());
1223  return 0;
1224  }
1225  static errno_t Unbox(const MpObject* This, std::unordered_map<K, V, Hash, Pr, Alloc>* m) {
1226  if (NLIB_UNLIKELY(!m)) return EINVAL;
1227  if (NLIB_UNLIKELY(This->type_ != kMap)) return EACCES;
1228  m->clear();
1229  for (uint32_t i = 0; i < This->size_; ++i) {
1230  K key;
1231  V value;
1232  const MpObjectKv& kv = (*This->via_.mp)[i];
1233  ErrnoT e;
1234  e = kv.first.Unbox(&key);
1235  if (NLIB_UNLIKELY(e != 0)) return e; // *m NOT RESET
1236  e = kv.second.Unbox(&value);
1237  if (NLIB_UNLIKELY(e != 0)) return e; // *m NOT RESET
1238  NLIB_TRY { (*m)[NLIB_MOVE(key)] = NLIB_MOVE(value); }
1239  NLIB_CATCH(...) { return ENOMEM; }
1240  }
1241  return 0;
1242  }
1243 };
1244 #endif
1245 
1246 NLIB_VIS_PUBLIC bool operator==(const MpObject& lhs, const MpObject& rhs);
1247 inline bool operator==(const MpObjectKv& lhs, const MpObjectKv& rhs) NLIB_NOEXCEPT {
1248  return lhs.first == rhs.first && lhs.second == rhs.second;
1249 }
1250 inline bool operator!=(const MpObject& lhs, const MpObject& rhs) NLIB_NOEXCEPT {
1251  return !(lhs == rhs);
1252 }
1253 inline bool operator!=(const MpObjectKv& lhs, const MpObjectKv& rhs) NLIB_NOEXCEPT {
1254  return !(lhs == rhs);
1255 }
1256 
1257 template<uint32_t n>
1259  uint32_t nn = static_cast<uint32_t>(nlib_strlen(str));
1260  ErrnoT e = this->InitString(nn);
1261  if (NLIB_UNLIKELY(e != 0)) return e;
1262  nlib_memcpy(this->GetString(), nn, static_cast<const void*>(&str[0]), nn);
1263  return 0;
1264 }
1265 
1266 template<class T, uint32_t n>
1267 errno_t MpObject::Box(const T (&vec)[n]) {
1268  MpObject tmp;
1269  ErrnoT e = tmp.InitArray(n);
1270  if (NLIB_UNLIKELY(e != 0)) return e;
1271  for (uint32_t i = 0; i < n; ++i) {
1272  e = (*tmp.via_.ary)[i].Box(vec[i]);
1273  if (NLIB_UNLIKELY(e != 0)) return e;
1274  }
1275  this->assign(tmp, move_tag());
1276  return 0;
1277 }
1278 
1279 #ifdef __cpp_rvalue_references
1280 template<class T, size_t n>
1281 errno_t MpObject::Box(const std::array<T, n>& vec) {
1282  MpObject tmp;
1283  ErrnoT e = tmp.InitArray(n);
1284  if (NLIB_UNLIKELY(e != 0)) return e;
1285  for (uint32_t i = 0; i < n; ++i) {
1286  e = (*tmp.via_.ary)[i].Box(vec[i]);
1287  if (NLIB_UNLIKELY(e != 0)) return e;
1288  }
1289  this->assign(tmp, move_tag());
1290  return 0;
1291 }
1292 #endif
1293 
1294 template<class T>
1295 errno_t MpObject::Unbox(T* a, size_t n) const {
1296  NLIB_EINVAL_IFNULL(a);
1297  if (NLIB_UNLIKELY(n == 0)) return EINVAL;
1298  if (NLIB_UNLIKELY(type_ != kArray)) return EACCES;
1299  if (NLIB_UNLIKELY(n != size_)) return ERANGE;
1300  for (uint32_t i = 0; i < size_; ++i) {
1301  ErrnoT e = (*via_.ary)[i].Unbox(&a[i]);
1302  if (NLIB_UNLIKELY(e != 0)) return e;
1303  }
1304  return 0;
1305 }
1306 
1307 } // namespace msgpack
1308 NLIB_NAMESPACE_END
1309 
1310 NLIB_DEFINE_STD_SWAP(::nlib_ns::msgpack::MpObject)
1311 NLIB_DEFINE_STD_SWAP(::nlib_ns::msgpack::MpObjectKv)
1312 
1313 #if defined(_MSC_VER) && defined(nx_msgpack_EXPORTS)
1314 #undef NLIB_VIS_PUBLIC
1315 #define NLIB_VIS_PUBLIC NLIB_WINIMPORT
1316 #endif
1317 
1318 #endif // INCLUDE_NN_NLIB_MSGPACK_MPOBJECT_H_
const nlib_utf8_t * const_iterator
Read-only random-access iterator.
Definition: MpObject.h:623
nlib_utf8_t * GetString() noexcept
Gets a string from an object.
Definition: MpObject.h:214
The class for providing access with character elements for MpObject that has the string (ASCII or UTF...
Definition: MpObject.h:620
std::reverse_iterator< iterator > reverse_iterator
A reverse iterator.
Definition: MpObject.h:624
iterator begin() noexcept
Gets the iterator pointing to the first element.
Definition: MpObject.h:635
iterator end() noexcept
Gets the iterator pointing beyond the last element.
Definition: MpObject.h:636
iterator end() noexcept
Gets the iterator pointing beyond the last element.
Definition: MpObject.h:548
const_reverse_iterator rbegin() const noexcept
Gets the read-only reverse iterator pointing to the last element.
Definition: MpObject.h:641
The class for providing access with MpObject stored in an array as an element for MpObject that has a...
Definition: MpObject.h:440
errno_t Unbox(T v) const
Unboxes the object.
Definition: MpObject.h:316
MpObject * pointer
Pointer to the element.
Definition: MpObject.h:446
bool IsString() const noexcept
Determines whether the stored value is a string.
Definition: MpObject.h:368
bool IsMap() const noexcept
Determines whether the stored value is an associative array.
Definition: MpObject.h:372
size_t size() const noexcept
Returns the length of the string.
Definition: MpObject.h:662
reference operator[](size_t n) noexcept
Gets the nth element. n must be less than the number of stored elements.
Definition: MpObject.h:720
The class for providing access with a pair of the key and the value as an element for MpObject that h...
Definition: MpObject.h:534
reference operator[](size_t n) noexcept
Returns a reference to the character at the specified position.
Definition: MpObject.h:648
MpObjectKv() noexcept
Instantiates the object with default parameters (default constructor).
Definition: MpObject.h:412
const_reference back() const noexcept
Gets a reference to the last element.
Definition: MpObject.h:462
reference operator[](size_t n) noexcept
Gets the nth element. n must be less than the number of stored elements.
Definition: MpObject.h:551
The class for providing access for extended data type MpObject.
Definition: MpObject.h:762
const nlib_byte_t * const_iterator
Read-only random-access iterator.
Definition: MpObject.h:695
size_t GetSize() const noexcept
Returns the number of stored elements.
Definition: MpObject.h:471
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
Prohibits use of the copy constructor and assignment operator for the class specified by TypeName...
Definition: Config.h:183
The class to provide access with byte data as an element for MpObject.
Definition: MpObject.h:692
Represents an unsigned integer type. The internal representation is uint64_t.
Definition: MpObject.h:339
const MpObject & operator[](size_t n) const
The const decoration version of the above function.
Definition: MpObject.h:140
const void * GetExtData() const noexcept
The const decoration version of the above function.
Definition: MpObject.h:770
errno_t PopBack() noexcept
Removes the end element.
Definition: MpObject.h:592
Represents an integer type. The internal representation is int64_t.
Definition: MpObject.h:340
std::reverse_iterator< iterator > reverse_iterator
A reverse iterator.
Definition: MpObject.h:696
int8_t GetExtType() const noexcept
Returns a signed 8-bit integer indicating the extended data type.
Definition: MpObject.h:771
void * GetExtData() noexcept
Returns the pointer to the beginning of binary data.
Definition: MpObject.h:769
uint32_t GetSize() const noexcept
Returns the number of stored elements.
Definition: MpObject.h:568
MpObjectAsString(MpObject &obj) noexcept
Definition: MpObject.h:632
Definition: Base64.h:25
const_reference at(size_t n) const noexcept
Returns a reference to the character at the specified position.
Definition: MpObject.h:654
~MpObject() noexcept
Destructor.
Definition: MpObject.h:171
const void * GetExt(int8_t *tp, uint32_t *n) const noexcept
Gets an extended data type from an object.
Definition: MpObject.h:235
Represents an array. The internal representation is an array of MpObject.
Definition: MpObject.h:344
const_reference front() const noexcept
Gets a reference to the first element.
Definition: MpObject.h:460
const_iterator begin() const noexcept
Gets the read-only iterator pointing to the first element.
Definition: MpObject.h:710
const_reference operator[](size_t n) const noexcept
The const decoration version of the above function.
Definition: MpObject.h:649
STL namespace.
Nlist< MpObjectKv >::iterator iterator
A forward iterator.
Definition: MpObject.h:536
size_t max_size() const noexcept
Returns the length of the string. (The string length is not altered).
Definition: MpObject.h:664
const void * GetBinary(uint32_t *n) const noexcept
Gets binary from an object.
Definition: MpObject.h:231
errno_t Resize(size_t n) noexcept
Changes the number of elements for an associative array.
Definition: MpObject.h:569
#define NLIB_UNLIKELY(x)
Indicates to the compiler that condition x is likely to be false.
Definition: Platform_unix.h:98
const nlib_utf8_t * GetString() const noexcept
The const decoration version of the above function.
Definition: MpObject.h:227
const_iterator begin() const noexcept
Gets the read-only iterator pointing to the first element.
Definition: MpObject.h:549
const_iterator end() const noexcept
Gets the read-only iterator pointing beyond the last element.
Definition: MpObject.h:458
bool operator==(const HeapHash &rhs, const HeapHash &lhs)
Returns true if the two compared summaries are equal.
Definition: NMalloc.h:130
bool operator!=(const HeapHash &rhs, const HeapHash &lhs)
Returns true if the two compared summaries are not equal.
Definition: NMalloc.h:135
int64_t nlib_time
The type expressing the time in increments of 100 ns from the zero starting point of 1970-01-01...
Definition: Platform.h:452
const_reverse_iterator rend() const noexcept
Gets the read-only reverse iterator pointing ahead of the first element.
Definition: MpObject.h:644
const nlib_utf8_t * data() const noexcept
Returns a C string.
Definition: MpObject.h:668
errno_t Box(const T &v)
Boxes the object.
Definition: MpObject.h:288
uint32_t GetSize() const noexcept
Returns the length of binary data.
Definition: MpObject.h:772
MpObjectKv & reference
A reference to an element.
Definition: MpObject.h:538
BaseType::const_iterator const_iterator
Read-only forward iterator.
Definition: Nlist.h:436
Represents binary data only for msgpack.
Definition: MpObject.h:346
#define NLIB_VIS_PUBLIC
Symbols for functions and classes are made available outside of the library.
Definition: Platform_unix.h:87
const_reference operator[](size_t n) const noexcept
The const decoration version of the above function.
Definition: MpObject.h:555
MpObjectAsBinary(MpObject &obj) noexcept
Definition: MpObject.h:705
nlib_utf8_t & reference
A reference to an element.
Definition: MpObject.h:626
Nlist< MpObjectKv >::const_iterator const_iterator
Read-only forward iterator.
Definition: MpObject.h:537
Object created when MessagePack or JSON is read.
Definition: MpObject.h:96
Represents a floating point type. The internal representation is float.
Definition: MpObject.h:341
const MpObjectKv * const_pointer
Read-only pointer to an element.
Definition: MpObject.h:541
MpObjectKv & assign(MpObjectKv &rhs, move_tag) noexcept
Corresponds to a move assignment operator.
Definition: MpObject.h:430
iterator end() noexcept
Gets the iterator pointing beyond the last element.
Definition: MpObject.h:456
const_iterator end() const noexcept
Gets the read-only iterator pointing beyond the last element.
Definition: MpObject.h:638
reference operator[](size_t n) noexcept
Gets the nth element. n must be less than the number of stored elements.
Definition: MpObject.h:463
errno_t PushBack(MpObject &&rhs) noexcept
Adds an element to the end of an array. The content in rhs is moved.
Definition: MpObject.h:481
const_reverse_iterator rbegin() const noexcept
Gets the read-only reverse iterator pointing to the last element.
Definition: MpObject.h:714
MpObject(MpObject &rhs, move_tag) noexcept
Corresponds to a move constructor.
Definition: MpObject.h:184
MpObject(MpObject &&rhs) noexcept
Instantiates the object (move constructor).
Definition: MpObject.h:173
errno_t PushBack(const nlib_utf8_t *key, MpObject &&value) noexcept
Adds a pair of the key and the value to the end of an associative array. The content in value is move...
Definition: MpObject.h:584
MpObject & operator=(const T &x)
The value is passed into MpObject.
Definition: MpObject.h:328
size_t length() const noexcept
Returns the length of the string.
Definition: MpObject.h:663
MpObject second
Object used as a value.
Definition: MpObject.h:409
const_iterator end() const noexcept
Gets the read-only iterator pointing beyond the last element.
Definition: MpObject.h:550
Defines the class that resembles std::vector but can store objects that cannot be copied...
ObjectType
Data type of the object stored in MpObject.
Definition: MpObject.h:336
const MpObject * const_pointer
Read-only pointer to an element.
Definition: MpObject.h:447
errno_t Resize(size_t n) noexcept
Changes the number of elements for an array.
Definition: MpObject.h:472
An empty structure indicating that an argument to a function needs to be moved.
Definition: Config.h:270
bool IsExt() const noexcept
Determines whether the stored value is extended data.
Definition: MpObject.h:370
errno_t Insert(size_t n, MpObject &&rhs) noexcept
Inserts rhs immediately before the nth element.
Definition: MpObject.h:489
MpObject & operator=(MpObject &&rhs) noexcept
Move assignment operator.
Definition: MpObject.h:177
errno_t InitArray(uint32_t n) noexcept
Initializes as an object with an n element array.
iterator begin() noexcept
Gets the iterator pointing to the first element.
Definition: MpObject.h:708
Represents a floating point type. The internal representation is double.
Definition: MpObject.h:342
errno_t Unbox(const MpObject *obj, T *v)
This function template can be specialized to define unboxing the user type.
bool IsNil() const noexcept
Determines whether the stored value is nil.
Definition: MpObject.h:360
bool empty() const noexcept
Returns true for an empty string.
Definition: MpObject.h:665
MpObjectAsMap(MpObject &obj) noexcept
Definition: MpObject.h:546
reference front() noexcept
Gets a reference to the first element.
Definition: MpObject.h:459
#define NLIB_LIKELY(x)
Indicates to the compiler that condition x is likely to be true.
Definition: Platform_unix.h:97
const nlib_utf8_t * c_str() const noexcept
Returns a C string.
Definition: MpObject.h:667
#define NLIB_CATCH(x)
Defines catch(x) if exceptions are enabled. If not, defines if (true).
Definition: Config.h:147
errno_t Erase(size_t n) noexcept
Removes the nth element.
Definition: MpObject.h:496
errno_t Erase(size_t n) noexcept
Removes the pair of the nth key in an associative array and the value.
Definition: MpObject.h:601
const_iterator begin() const noexcept
Gets the read-only iterator pointing to the first element.
Definition: MpObject.h:637
nlib_utf8_t * iterator
A random-access iterator.
Definition: MpObject.h:622
errno_t InitString(uint32_t n) noexcept
Initializes the object as a string.
Class that wraps errno_t. This class improves visual representations in the Visual Studio debugger...
Definition: Config.h:404
const_reverse_iterator rend() const noexcept
Gets the read-only reverse iterator pointing ahead of the first element.
Definition: MpObject.h:717
#define NLIB_TRY
Defines try if exceptions are enabled. If not, defines if (true).
Definition: Config.h:146
nlib_byte_t & reference
A reference to an element.
Definition: MpObject.h:698
ObjectType GetType() const noexcept
Returns the object type.
Definition: MpObject.h:353
reverse_iterator rend() noexcept
Gets the reverse iterator pointing ahead of the first element.
Definition: MpObject.h:713
BaseType::iterator iterator
A forward iterator.
Definition: Nlist.h:435
errno_t PushBack(MpObjectKv &&rhs) noexcept
Adds a pair of the key and the value to the end of an associative array. The content in rhs is moved...
Definition: MpObject.h:578
bool IsArray() const noexcept
Determines whether the stored value is an array.
Definition: MpObject.h:371
MpObject(const T &x)
The constructor for boxing a T-type object.
Definition: MpObject.h:197
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
Definition: Config.h:109
MpObjectAsExt(MpObject &obj) noexcept
Definition: MpObject.h:768
const nlib_byte_t & const_reference
Read-only reference to an element.
Definition: MpObject.h:699
const MpObjectKv & const_reference
Read-only reference to an element.
Definition: MpObject.h:539
errno_t Unbox(nlib_utf8_t(&str)[n]) const noexcept
See Unbox(T (&a)[n]).
Definition: MpObject.h:307
const MpObject * GetMapItem(const STDSTRING &str) const noexcept
The const decoration version of the above function.
Definition: MpObject.h:156
A file that contains the configuration information for each development environment.
~MpObjectKv() noexcept
Destructor.
Definition: MpObject.h:413
Represents a boolean type. The internal representation is a bool.
Definition: MpObject.h:338
reverse_iterator rend() noexcept
Gets the reverse iterator pointing ahead of the first element.
Definition: MpObject.h:640
uint32_t GetSize() const noexcept
Returns the size of the array, associative array, string, or binary.
Definition: MpObject.h:354
iterator end() noexcept
Gets the iterator pointing beyond the last element.
Definition: MpObject.h:709
MpObjectAsArray(MpObject &obj) noexcept
Definition: MpObject.h:452
A container-like class similar to std::vector that can store objects that do not have copy constructo...
Definition: Nlist.h:32
uint32_t GetSize() const noexcept
Returns the length of the string.
Definition: MpObject.h:659
Nlist< MpObject >::iterator iterator
A forward iterator.
Definition: MpObject.h:442
reference back() noexcept
Gets a reference to the last element.
Definition: MpObject.h:461
errno_t RemoveMapItem(const STDSTRING &str, MpObjectKv *kv) noexcept
Specifies a key and deletes the corresponding key and object in the associative array.
Definition: MpObject.h:223
MpObject & assign(MpObject &rhs, move_tag) noexcept
Assigns the object by using swap for a move.
Definition: MpObject.h:188
Respresents a byte array (string).
Definition: MpObject.h:343
const_iterator end() const noexcept
Gets the read-only iterator pointing beyond the last element.
Definition: MpObject.h:711
const MpObject & const_reference
Read-only reference to an element.
Definition: MpObject.h:445
static bool IsJsonPointer(const nlib_utf8_t *str) noexcept
A parameter omitted version of the above function which receives a null terminated string...
Definition: MpObject.h:111
size_t nlib_strlen(const char *s)
Internally calls strlen(). In some cases, it may operate as an independent implementation.
bool IsBoolean() const noexcept
Determines whether the stored value is a boolean.
Definition: MpObject.h:361
Wraps functions like strlen and strcpy so they can be safely used.
bool IsFloat() const noexcept
Determines whether the stored value is a single precision float.
Definition: MpObject.h:366
MpObject first
Object used as a key.
Definition: MpObject.h:408
#define NLIB_FINAL
Defines final if it is available for use. If not, holds an empty string.
Definition: Config.h:250
MpObject * GetMapItem(const STDSTRING &str) noexcept
Specifies a string and gets the object in the associative array.
Definition: MpObject.h:160
nlib_byte_t * iterator
A random-access iterator.
Definition: MpObject.h:694
iterator begin() noexcept
Gets the iterator pointing to the first element.
Definition: MpObject.h:455
uint32_t GetSize() const noexcept
Returns the number of stored elements.
Definition: MpObject.h:722
bool IsDouble() const noexcept
Determines whether the stored value is a double.
Definition: MpObject.h:367
A pair consisting of an MpObject-type key and value. Used to store an associative array...
Definition: MpObject.h:407
reverse_iterator rbegin() noexcept
Gets the reverse iterator pointing to the last element.
Definition: MpObject.h:639
const_reference operator[](size_t n) const noexcept
The const decoration version of the above function.
Definition: MpObject.h:721
const_reference operator[](size_t n) const noexcept
The const decoration version of the above function.
Definition: MpObject.h:467
const_iterator begin() const noexcept
Gets the read-only iterator pointing to the first element.
Definition: MpObject.h:457
MpObject & reference
A reference to an element.
Definition: MpObject.h:444
errno_t GetMapItem(const nlib_utf8_t *str, size_t n, MpObjectKv **obj) noexcept
Obtains the pair of a key and value from the associative array by specifying a non-null terminated st...
Definition: MpObject.h:205
unsigned char nlib_byte_t
This type will be defined as std::byte in a typedef of C++17 or later.
Definition: Platform.h:314
reverse_iterator rbegin() noexcept
Gets the reverse iterator pointing to the last element.
Definition: MpObject.h:712
iterator begin() noexcept
Gets the iterator pointing to the first element.
Definition: MpObject.h:547
const nlib_utf8_t & const_reference
Read-only reference to an element.
Definition: MpObject.h:627
errno_t PopBack() noexcept
Removes the end element.
Definition: MpObject.h:503
Class that corresponds to nil in MessagePack and null in JSON.
Definition: MpObject.h:52
MpObjectKv * pointer
Pointer to the element.
Definition: MpObject.h:540
#define NLIB_NONNULL
Indicates that you cannot specify NULL for all arguments.
bool IsInteger() const noexcept
Determines whether the stored value is an integer.
Definition: MpObject.h:362
bool IsBinary() const noexcept
Determines whether the stored value is binary.
Definition: MpObject.h:369
Represents an associative array. The internal representation is an array of MpObject pairs...
Definition: MpObject.h:345
MpObjectKv(MpObjectKv &rhs, move_tag) noexcept
Corresponds to a move constructor.
Definition: MpObject.h:428
std::reverse_iterator< const_iterator > const_reverse_iterator
Read-only reverse iterator.
Definition: MpObject.h:625
errno_t Unbox(T(&a)[n]) const
Unboxes the object value.
Definition: MpObject.h:297
errno_t Box(MpObject *obj, const T &v)
This function template can be specialized to define boxing the user type.
Represents the extended data type only for msgpack.
Definition: MpObject.h:347
Nlist< MpObject >::const_iterator const_iterator
Read-only forward iterator.
Definition: MpObject.h:443
char nlib_utf8_t
Defines char with a typedef. Indicates that it is a UTF-8 string.
Definition: Platform.h:303
std::reverse_iterator< const_iterator > const_reverse_iterator
Read-only reverse iterator.
Definition: MpObject.h:697
reference at(size_t n) noexcept
Returns a reference to the character at the specified position.
Definition: MpObject.h:650
int errno_t
Indicates with an int-type typedef that a POSIX error value is returned as the return value...
Definition: NMalloc.h:37