nlib
MpObject.h
[詳解]
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
読み取り専用ランダムアクセス反復子です。
Definition: MpObject.h:623
nlib_utf8_t * GetString() noexcept
オブジェクトから文字列を取得します。
Definition: MpObject.h:214
文字列(ASCII又はUTF-8)型を持つMpObjectに対して、文字を要素とするアクセスを提供するためのクラスです。 ...
Definition: MpObject.h:620
std::reverse_iterator< iterator > reverse_iterator
逆反復子です。
Definition: MpObject.h:624
iterator begin() noexcept
先頭要素を指す反復子を取得します。
Definition: MpObject.h:635
iterator end() noexcept
末尾の次を指す反復子を取得します。
Definition: MpObject.h:636
iterator end() noexcept
末尾の次を指す反復子を取得します。
Definition: MpObject.h:548
const_reverse_iterator rbegin() const noexcept
末尾要素を指す読み取り専用逆反復子を取得します。
Definition: MpObject.h:641
配列型を持つMpObjectに対して、配列に格納されたMpObjectを要素とするアクセスを提供するためのクラスです...
Definition: MpObject.h:440
errno_t Unbox(T v) const
オブジェクトをアンボックス化します。
Definition: MpObject.h:316
MpObject * pointer
要素へのポインタです。
Definition: MpObject.h:446
bool IsString() const noexcept
格納されている値が文字列であるかどうかを調べます。
Definition: MpObject.h:368
bool IsMap() const noexcept
格納されている値が連想配列であるかどうかを調べます。
Definition: MpObject.h:372
size_t size() const noexcept
文字列長を返します。
Definition: MpObject.h:662
reference operator[](size_t n) noexcept
n番目の要素を取得します。nは格納されている要素数未満である必要があります。
Definition: MpObject.h:720
連想配列型を持つMpObjectに対して、キーと値のペアを要素とするアクセスを提供するためのクラスです。 ...
Definition: MpObject.h:534
reference operator[](size_t n) noexcept
指定された位置の文字への参照を返します。
Definition: MpObject.h:648
MpObjectKv() noexcept
デフォルトコンストラクタです。
Definition: MpObject.h:412
const_reference back() const noexcept
最後の要素への参照を取得します。
Definition: MpObject.h:462
reference operator[](size_t n) noexcept
n番目の要素を取得します。nは格納されている要素数未満である必要があります。
Definition: MpObject.h:551
拡張データ型のMpObjectに対してアクセスを提供するためのクラスです。
Definition: MpObject.h:762
const nlib_byte_t * const_iterator
読み取り専用ランダムアクセス反復子です。
Definition: MpObject.h:695
size_t GetSize() const noexcept
格納されている要素数を返します。
Definition: MpObject.h:471
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
TypeName で指定されたクラスのコピーコンストラクタと代入演算子を禁止します。
Definition: Config.h:183
バイナリのMpObjectに対して、バイトデータを要素とするアクセスを提供するためのクラスです。 ...
Definition: MpObject.h:692
非負整数型を表します。内部表現はuint64_tです。
Definition: MpObject.h:339
const MpObject & operator[](size_t n) const
上記関数のconst修飾付き版です。
Definition: MpObject.h:140
const void * GetExtData() const noexcept
上記関数のconst修飾付き版です。
Definition: MpObject.h:770
errno_t PopBack() noexcept
末尾の要素を取り除きます。
Definition: MpObject.h:592
整数型を表します。内部表現はint64_tです。
Definition: MpObject.h:340
std::reverse_iterator< iterator > reverse_iterator
逆反復子です。
Definition: MpObject.h:696
int8_t GetExtType() const noexcept
拡張データ型の型を示す8bit符号付き整数を返します。
Definition: MpObject.h:771
void * GetExtData() noexcept
バイナリデータの先頭へのポインタを返します。
Definition: MpObject.h:769
uint32_t GetSize() const noexcept
格納されている要素数を返します。
Definition: MpObject.h:568
MpObjectAsString(MpObject &obj) noexcept
Definition: MpObject.h:632
Definition: Base64.h:25
const_reference at(size_t n) const noexcept
指定された位置の文字への参照を返します。
Definition: MpObject.h:654
~MpObject() noexcept
デストラクタです。
Definition: MpObject.h:171
const void * GetExt(int8_t *tp, uint32_t *n) const noexcept
オブジェクトから拡張データ型を取得します。
Definition: MpObject.h:235
配列を表します。内部ではMpObjectの列として表現されています。
Definition: MpObject.h:344
const_reference front() const noexcept
最初の要素への参照を取得します。
Definition: MpObject.h:460
const_iterator begin() const noexcept
先頭要素を指す読み取り専用反復子を取得します。
Definition: MpObject.h:710
const_reference operator[](size_t n) const noexcept
上記関数のconst修飾付き版です。
Definition: MpObject.h:649
STL namespace
Nlist< MpObjectKv >::iterator iterator
前方反復子です。
Definition: MpObject.h:536
size_t max_size() const noexcept
文字列長を返します。 (文字列長が不変のため)。
Definition: MpObject.h:664
const void * GetBinary(uint32_t *n) const noexcept
オブジェクトからバイナリを取得します。
Definition: MpObject.h:231
errno_t Resize(size_t n) noexcept
連想配列の要素数を変更します。
Definition: MpObject.h:569
#define NLIB_UNLIKELY(x)
条件xが偽になる傾向が高いことをコンパイラに示します。
Definition: Platform_unix.h:98
const nlib_utf8_t * GetString() const noexcept
上記関数のconst修飾付き版です。
Definition: MpObject.h:227
const_iterator begin() const noexcept
先頭要素を指す読み取り専用反復子を取得します。
Definition: MpObject.h:549
const_iterator end() const noexcept
末尾の次を指す読み取り専用反復子を取得します。
Definition: MpObject.h:458
bool operator==(const HeapHash &rhs, const HeapHash &lhs)
2つのサマリを比較して等価ならば、trueを返します。
Definition: NMalloc.h:130
bool operator!=(const HeapHash &rhs, const HeapHash &lhs)
2つのサマリを比較して等価でなければ、trueを返します。
Definition: NMalloc.h:135
int64_t nlib_time
1970/01/01を起点(0)としてから100ns刻みで時刻を表現する型です。64bit符号付き整数です。 ...
Definition: Platform.h:452
const_reverse_iterator rend() const noexcept
先頭の前を指す読み取り専用逆反復子を取得します。
Definition: MpObject.h:644
const nlib_utf8_t * data() const noexcept
C文字列を返します。
Definition: MpObject.h:668
errno_t Box(const T &v)
オブジェクトをボックス化します。
Definition: MpObject.h:288
uint32_t GetSize() const noexcept
バイナリデータのデータ長を返します。
Definition: MpObject.h:772
MpObjectKv & reference
要素への参照です。
Definition: MpObject.h:538
BaseType::const_iterator const_iterator
読み取り専用前方反復子です。
Definition: Nlist.h:436
msgpack専用でバイナリデータを表します。
Definition: MpObject.h:346
#define NLIB_VIS_PUBLIC
関数やクラス等のシンボルをライブラリの外部に公開します。
Definition: Platform_unix.h:87
const_reference operator[](size_t n) const noexcept
上記関数のconst修飾付き版です。
Definition: MpObject.h:555
MpObjectAsBinary(MpObject &obj) noexcept
Definition: MpObject.h:705
nlib_utf8_t & reference
要素への参照です。
Definition: MpObject.h:626
Nlist< MpObjectKv >::const_iterator const_iterator
読み取り専用前方反復子です。
Definition: MpObject.h:537
MessagePack又はJSONを読み込むことで作成されるオブジェクトです。
Definition: MpObject.h:96
浮動小数型を表します。内部表現はfloatです。
Definition: MpObject.h:341
const MpObjectKv * const_pointer
要素への読み取り専用ポインタです。
Definition: MpObject.h:541
MpObjectKv & assign(MpObjectKv &rhs, move_tag) noexcept
ムーブ代入演算子に相当します。
Definition: MpObject.h:430
iterator end() noexcept
末尾の次を指す反復子を取得します。
Definition: MpObject.h:456
const_iterator end() const noexcept
末尾の次を指す読み取り専用反復子を取得します。
Definition: MpObject.h:638
reference operator[](size_t n) noexcept
n番目の要素を取得します。nは格納されている要素数未満である必要があります。
Definition: MpObject.h:463
errno_t PushBack(MpObject &&rhs) noexcept
配列の末尾に要素を追加します。rhsの内容はムーブされます。
Definition: MpObject.h:481
const_reverse_iterator rbegin() const noexcept
末尾要素を指す読み取り専用逆反復子を取得します。
Definition: MpObject.h:714
MpObject(MpObject &rhs, move_tag) noexcept
ムーブコンストラクタに相当します。
Definition: MpObject.h:184
MpObject(MpObject &&rhs) noexcept
ムーブコンストラクタです。
Definition: MpObject.h:173
errno_t PushBack(const nlib_utf8_t *key, MpObject &&value) noexcept
連想配列の末尾にキーと値のペアを追加します。valueの内容はムーブされます。
Definition: MpObject.h:584
MpObject & operator=(const T &x)
値をMpObjectに代入します。
Definition: MpObject.h:328
size_t length() const noexcept
文字列長を返します。
Definition: MpObject.h:663
MpObject second
値となるオブジェクトです。
Definition: MpObject.h:409
const_iterator end() const noexcept
末尾の次を指す読み取り専用反復子を取得します。
Definition: MpObject.h:550
std::vectorに似ていますが、コピーできないオブジェクトを格納可能なクラスが定義されています。 ...
ObjectType
MpObjectに格納されているオブジェクトの型情報です。
Definition: MpObject.h:336
const MpObject * const_pointer
要素への読み取り専用ポインタです。
Definition: MpObject.h:447
errno_t Resize(size_t n) noexcept
配列の要素数を変更します。
Definition: MpObject.h:472
空の構造体で、関数の引数をムーブすべきことを示すために利用されます。
Definition: Config.h:270
bool IsExt() const noexcept
格納されている値が拡張データであるかどうかを調べます。
Definition: MpObject.h:370
errno_t Insert(size_t n, MpObject &&rhs) noexcept
n番目の要素の直前にrhsを挿入します。
Definition: MpObject.h:489
MpObject & operator=(MpObject &&rhs) noexcept
ムーブ代入演算子です。
Definition: MpObject.h:177
errno_t InitArray(uint32_t n) noexcept
オブジェクトをn 個の要素を持つ配列として初期化します。
iterator begin() noexcept
先頭要素を指す反復子を取得します。
Definition: MpObject.h:708
浮動小数型を表します。内部表現はdoubleです。
Definition: MpObject.h:342
errno_t Unbox(const MpObject *obj, T *v)
この関数テンプレートを特殊化してユーザー型のアンボックス化を定義することが可能です。 ...
bool IsNil() const noexcept
格納されている値ががnilであるかどうかを調べます。
Definition: MpObject.h:360
bool empty() const noexcept
空文字列の場合は真を返します。
Definition: MpObject.h:665
MpObjectAsMap(MpObject &obj) noexcept
Definition: MpObject.h:546
reference front() noexcept
最初の要素への参照を取得します。
Definition: MpObject.h:459
#define NLIB_LIKELY(x)
条件xが真になる傾向が高いことをコンパイラに示します。
Definition: Platform_unix.h:97
const nlib_utf8_t * c_str() const noexcept
C文字列を返します。
Definition: MpObject.h:667
#define NLIB_CATCH(x)
例外が有効なときはcatch(x), そうでなければif (true)が定義されます。
Definition: Config.h:147
errno_t Erase(size_t n) noexcept
n番目の要素を取り除きます。
Definition: MpObject.h:496
errno_t Erase(size_t n) noexcept
連想配列のn番目のキーと値のペアを取り除きます。
Definition: MpObject.h:601
const_iterator begin() const noexcept
先頭要素を指す読み取り専用反復子を取得します。
Definition: MpObject.h:637
nlib_utf8_t * iterator
ランダムアクセス反復子です。
Definition: MpObject.h:622
errno_t InitString(uint32_t n) noexcept
オブジェクトを文字列として初期化します。
errno_tをラップするクラスです。Visual Studioのデバッガ上での表示を改善します。
Definition: Config.h:404
const_reverse_iterator rend() const noexcept
先頭の前を指す読み取り専用逆反復子を取得します。
Definition: MpObject.h:717
#define NLIB_TRY
例外が有効なときはtry, そうでなければif (true)が定義されます。
Definition: Config.h:146
nlib_byte_t & reference
要素への参照です。
Definition: MpObject.h:698
ObjectType GetType() const noexcept
オブジェクトの型を返します。
Definition: MpObject.h:353
reverse_iterator rend() noexcept
先頭の前を指す逆反復子を取得します。
Definition: MpObject.h:713
BaseType::iterator iterator
前方反復子です。
Definition: Nlist.h:435
errno_t PushBack(MpObjectKv &&rhs) noexcept
連想配列の末尾にキーと値のペアを追加します。rhsの内容はムーブされます。
Definition: MpObject.h:578
bool IsArray() const noexcept
格納されている値が配列であるかどうかを調べます。
Definition: MpObject.h:371
MpObject(const T &x)
T型のオブジェクトをボックス化するコンストラクタです。
Definition: MpObject.h:197
#define NLIB_NOEXCEPT
環境に合わせてnoexcept 又は同等の定義がされます。
Definition: Config.h:109
MpObjectAsExt(MpObject &obj) noexcept
Definition: MpObject.h:768
const nlib_byte_t & const_reference
要素への読み取り専用参照です。
Definition: MpObject.h:699
const MpObjectKv & const_reference
要素への読み取り専用参照です。
Definition: MpObject.h:539
errno_t Unbox(nlib_utf8_t(&str)[n]) const noexcept
Unbox(T (&a)[n]) を御覧ください。
Definition: MpObject.h:307
const MpObject * GetMapItem(const STDSTRING &str) const noexcept
上記関数のconst修飾付き版です。
Definition: MpObject.h:156
開発環境別の設定が書かれるファイルです。
~MpObjectKv() noexcept
デストラクタです。
Definition: MpObject.h:413
真偽値型を表します。内部表現はboolです。
Definition: MpObject.h:338
reverse_iterator rend() noexcept
先頭の前を指す逆反復子を取得します。
Definition: MpObject.h:640
uint32_t GetSize() const noexcept
配列や連想配列や文字列やバイナリの場合にそのサイズを返します。
Definition: MpObject.h:354
iterator end() noexcept
末尾の次を指す反復子を取得します。
Definition: MpObject.h:709
MpObjectAsArray(MpObject &obj) noexcept
Definition: MpObject.h:452
std::vectorに似た、コピーコンストラクタを持たないオブジェクトを格納可能なコンテナ類似クラスです。 ...
Definition: Nlist.h:32
uint32_t GetSize() const noexcept
文字列長を返します。
Definition: MpObject.h:659
Nlist< MpObject >::iterator iterator
前方反復子です。
Definition: MpObject.h:442
reference back() noexcept
最後の要素への参照を取得します。
Definition: MpObject.h:461
errno_t RemoveMapItem(const STDSTRING &str, MpObjectKv *kv) noexcept
キーを指定して連想配列内のキーとオブジェクトを削除します。
Definition: MpObject.h:223
MpObject & assign(MpObject &rhs, move_tag) noexcept
swapを利用したムーブにより代入します。
Definition: MpObject.h:188
バイト列(文字列)を表します。
Definition: MpObject.h:343
const_iterator end() const noexcept
末尾の次を指す読み取り専用反復子を取得します。
Definition: MpObject.h:711
const MpObject & const_reference
要素への読み取り専用参照です。
Definition: MpObject.h:445
static bool IsJsonPointer(const nlib_utf8_t *str) noexcept
上記関数の引数省略版で、ヌル終端する文字列を受け取ります。
Definition: MpObject.h:111
size_t nlib_strlen(const char *s)
内部でstrlen()を呼び出します。独自の実装が動作する場合もあります。
bool IsBoolean() const noexcept
格納されている値が真偽値であるかどうかを調べます。
Definition: MpObject.h:361
strlen, strcpy等を安全に使えるようにラップしています。
bool IsFloat() const noexcept
格納されている値が単精度浮動小数点型であるかどうかを調べます。
Definition: MpObject.h:366
MpObject first
キーとなるオブジェクトです。
Definition: MpObject.h:408
#define NLIB_FINAL
利用可能であればfinalが定義されます。そうでない場合は空文字列です。
Definition: Config.h:250
MpObject * GetMapItem(const STDSTRING &str) noexcept
文字列を指定して連想配列内のオブジェクトを取得します。
Definition: MpObject.h:160
nlib_byte_t * iterator
ランダムアクセス反復子です。
Definition: MpObject.h:694
iterator begin() noexcept
先頭要素を指す反復子を取得します。
Definition: MpObject.h:455
uint32_t GetSize() const noexcept
格納されている要素数を返します。
Definition: MpObject.h:722
bool IsDouble() const noexcept
格納されている値が倍精度浮動小数点型であるかどうかを調べます。
Definition: MpObject.h:367
MpObject型のキーと値のペアです。連想配列を格納するために利用されます。
Definition: MpObject.h:407
reverse_iterator rbegin() noexcept
末尾要素を指す逆反復子を取得します。
Definition: MpObject.h:639
const_reference operator[](size_t n) const noexcept
上記関数のconst修飾付き版です。
Definition: MpObject.h:721
const_reference operator[](size_t n) const noexcept
上記関数のconst修飾付き版です。
Definition: MpObject.h:467
const_iterator begin() const noexcept
先頭要素を指す読み取り専用反復子を取得します。
Definition: MpObject.h:457
MpObject & reference
要素への参照です。
Definition: MpObject.h:444
errno_t GetMapItem(const nlib_utf8_t *str, size_t n, MpObjectKv **obj) noexcept
キーとなる非ヌル終端の文字列を指定して連想配列のキーと値のペアを取得します。
Definition: MpObject.h:205
unsigned char nlib_byte_t
C++17以降でstd::byteにtypedefされる型です。
Definition: Platform.h:314
reverse_iterator rbegin() noexcept
末尾要素を指す逆反復子を取得します。
Definition: MpObject.h:712
iterator begin() noexcept
先頭要素を指す反復子を取得します。
Definition: MpObject.h:547
const nlib_utf8_t & const_reference
要素への読み取り専用参照です。
Definition: MpObject.h:627
errno_t PopBack() noexcept
末尾の要素を取り除きます。
Definition: MpObject.h:503
MessagePackのnil, 及びJSONのnullに対応するクラスです。
Definition: MpObject.h:52
MpObjectKv * pointer
要素へのポインタです。
Definition: MpObject.h:540
#define NLIB_NONNULL
全ての引数にNULLを指定することができないことを示します。
bool IsInteger() const noexcept
格納されている値が整数値であるかどうかを調べます。
Definition: MpObject.h:362
bool IsBinary() const noexcept
格納されている値がバイナリであるかどうかを調べます。
Definition: MpObject.h:369
連想配列を表します。内部ではMpObjectのペアの列として表現されています。
Definition: MpObject.h:345
MpObjectKv(MpObjectKv &rhs, move_tag) noexcept
ムーブコンストラクタに相当します。
Definition: MpObject.h:428
std::reverse_iterator< const_iterator > const_reverse_iterator
読み取り専用逆反復子です。
Definition: MpObject.h:625
errno_t Unbox(T(&a)[n]) const
オブジェクトの値をアンボックス化します。
Definition: MpObject.h:297
errno_t Box(MpObject *obj, const T &v)
この関数テンプレートを特殊化してユーザー型のボックス化を定義することが可能です。
msgpack専用で拡張データ型を表します。
Definition: MpObject.h:347
Nlist< MpObject >::const_iterator const_iterator
読み取り専用前方反復子です。
Definition: MpObject.h:443
char nlib_utf8_t
charのtypedefです。文字列がUTF-8であることを示します。
Definition: Platform.h:303
std::reverse_iterator< const_iterator > const_reverse_iterator
読み取り専用逆反復子です。
Definition: MpObject.h:697
reference at(size_t n) noexcept
指定された位置の文字への参照を返します。
Definition: MpObject.h:650
int errno_t
intのtypedefで、戻り値としてPOSIXのエラー値を返すことを示します。
Definition: NMalloc.h:37