16 #ifndef INCLUDE_NN_NLIB_MSGPACK_MPOBJECT_H_ 17 #define INCLUDE_NN_NLIB_MSGPACK_MPOBJECT_H_ 24 #include "nn/nlib/Swap.h" 28 #ifdef NLIB_CXX11_STDLIB_ARRAY 32 #ifdef NLIB_CXX11_STDLIB_UNORDERED 33 #include <unordered_map> 36 #ifdef NLIB_CXX11_STDLIB_TUPLE 40 #if defined(_MSC_VER) && defined(nx_msgpack_EXPORTS) 41 #undef NLIB_VIS_PUBLIC 42 #define NLIB_VIS_PUBLIC NLIB_WINEXPORT 117 return NLIB_LIKELY(0 == this->GetArrayItem(n, &obj)) ? obj : NULL;
121 return NLIB_LIKELY(0 == this->GetArrayItem(n, &obj)) ? obj : NULL;
124 NLIB_ASSERT(this->IsArray());
125 NLIB_ASSERT(n < size_);
126 return (*via_.ary)[n];
132 return GetMapItem(&str[0]);
136 return GetMapItem(&str[0]);
138 template<
class STDSTRING>
140 return GetMapItem(&str[0], str.size());
142 template<
class STDSTRING>
144 return GetMapItem(&str[0], str.size());
148 MpObject* p = this->GetArrayItem(n);
152 template<
class STDSTRING>
154 MpObject* p = this->GetMapItem(key);
160 return SwapMapItem(&key[0], obj);
163 MpObject* p = this->GetMapItem(key);
175 NLIB_MOVE_MEMBER_HELPER_1(
MpObject, type_);
180 MyBox<T, typename IsIntegral<T>::type,
typename IsSigned<T>::type>::Construct(
this, x);
187 MpObjectKv** obj) NLIB_NOEXCEPT NLIB_NONNULL {
189 errno_t e = this->GetMapItem(str, n, &kv);
190 if (e != 0)
return e;
197 if (type_ == kString)
return via_.str;
199 return reinterpret_cast<nlib_utf8_t*
>(&raw14data_);
205 template<
class STDSTRING>
207 return RemoveMapItem(str.c_str(), kv);
211 return const_cast<MpObject*
>(
this)->GetString();
214 if (type_ == kBinary) {
224 const void*
GetBinary(uint32_t* n)
const NLIB_NOEXCEPT {
225 return const_cast<MpObject*
>(
this)->GetBinary(n);
227 void*
GetExt(int8_t* tp, uint32_t* n) NLIB_NOEXCEPT {
230 *tp =
static_cast<int8_t
>(raw14data_);
236 const void*
GetExt(int8_t* tp, uint32_t* n)
const NLIB_NOEXCEPT {
237 return const_cast<MpObject*
>(
this)->GetExt(tp, n);
245 uint32_t n =
static_cast<uint32_t
>(
nlib_strlen(str));
246 return InitString(str, n);
255 template <u
int32_t n>
257 template <
class T, u
int32_t n>
259 #ifdef NLIB_CXX11_STDLIB_ARRAY 260 template <
class T,
size_t n>
265 return MyBox<T, typename IsIntegral<T>::type,
typename IsSigned<T>::type>
::Box(
this, v);
272 template <
class T,
size_t n>
274 return this->
Unbox(&a[0], n);
276 #ifdef NLIB_CXX11_STDLIB_ARRAY 277 template <
class T,
size_t n>
279 return this->
Unbox(reinterpret_cast<T*>(&*a.begin()), n);
284 return this->
Unbox(&str[0], n);
295 return MyBox<typename RemovePtr<T>::type,
296 typename IsIntegral<typename RemovePtr<T>::type>::type,
297 typename IsSigned<typename RemovePtr<T>::type>::type>
::Unbox(
this, v);
305 MyBox<T, typename IsIntegral<T>::type,
typename IsSigned<T>::type>::Assign(
this, x);
309 MpObject* Clone() NLIB_NOEXCEPT
const;
312 swap(type_, rhs.type_);
313 swap(raw14size_, rhs.raw14size_);
314 swap(raw14data_, rhs.raw14data_);
316 swap(size_, rhs.size_);
317 swap(via_.u64, rhs.via_.u64);
333 kStringInline = 0x80 | kString,
334 kBinaryInline = 0x80 | kBinary,
335 kBooleanFalse = 0x00 | kBoolean,
336 kBooleanTrue = 0x80 | kBoolean,
349 STRING_INLINE = kStringInline,
350 BINARY_INLINE = kBinaryInline,
351 RAW_INLINE = 0x80 | RAW,
352 BOOLEAN_FALSE = kBooleanFalse,
353 BOOLEAN_TRUE = kBooleanTrue
359 if (type_ == kStringInline || type_ == kBinaryInline)
364 bool IsNil() const NLIB_NOEXCEPT {
return GetType() == kNil; }
365 bool IsBoolean() const NLIB_NOEXCEPT {
return GetType() == kBoolean; }
368 return tp == kUint64 || tp == kInt64;
370 bool IsFloat() const NLIB_NOEXCEPT {
return GetType() == kFloat; }
371 bool IsDouble() const NLIB_NOEXCEPT {
return GetType() == kDouble; }
372 bool IsString() const NLIB_NOEXCEPT {
return GetType() == kString; }
373 bool IsBinary() const NLIB_NOEXCEPT {
return GetType() == kBinary; }
374 bool IsExt() const NLIB_NOEXCEPT {
return GetType() == kExt; }
375 bool IsArray() const NLIB_NOEXCEPT {
return GetType() == kArray; }
376 bool IsMap() const NLIB_NOEXCEPT {
return GetType() == kMap; }
380 template <
class T,
class IS_INTEGRAL,
class IS_SIGNED>
384 if (!v)
return EINVAL;
387 static void Assign(
MpObject* This,
const T& x);
388 static void Construct(
MpObject* This,
const T& x);
390 void ReleaseIfNeeded() NLIB_NOEXCEPT {
391 if (type_ >= kString && type_ <= kExt) ReleaseIfNeeded_();
413 NLIB_MOVE_MEMBER_HELPER_2(
MpObjectKv, first, second);
415 first.
swap(rhs.first);
416 second.
swap(rhs.second);
424 struct MpObject::MyBox<nil, FalseType, FalseType> {
427 This->ReleaseIfNeeded();
431 static void Assign(
MpObject* This, nil x) NLIB_NOEXCEPT { This->
Box(x); }
432 static void Construct(
MpObject* This, nil) NLIB_NOEXCEPT { This->type_ = kNil; }
436 struct MpObject::MyBox<bool, TrueType, FalseType> {
438 This->ReleaseIfNeeded();
439 This->type_ = v ?
static_cast<uint8_t
>(kBooleanTrue) : static_cast<uint8_t>(kBooleanFalse);
443 if (This->type_ == kBooleanFalse) {
446 }
else if (
NLIB_LIKELY(This->type_ == kBooleanTrue)) {
453 static void Assign(
MpObject* This,
bool x) NLIB_NOEXCEPT { This->
Box(x); }
454 static void Construct(
MpObject* This,
bool x) NLIB_NOEXCEPT {
455 This->type_ = x ?
static_cast<uint8_t
>(kBooleanTrue) : static_cast<uint8_t>(kBooleanFalse);
460 struct MpObject::MyBox<T, TrueType, TrueType> {
462 This->ReleaseIfNeeded();
463 This->type_ = kInt64;
469 if (This->type_ == kInt64) {
470 *v =
static_cast<T
>(This->via_.i64);
473 *v =
static_cast<T
>(This->via_.u64);
479 static void Assign(
MpObject* This, T x) NLIB_NOEXCEPT { This->
Box(x); }
480 static void Construct(
MpObject* This, T x) NLIB_NOEXCEPT {
481 This->type_ = kInt64;
487 struct MpObject::MyBox<T, TrueType, FalseType> {
489 This->ReleaseIfNeeded();
490 This->type_ = kUint64;
496 if (This->type_ == kInt64) {
497 *v =
static_cast<T
>(This->via_.i64);
500 *v =
static_cast<T
>(This->via_.u64);
506 static void Assign(
MpObject* This, T x) NLIB_NOEXCEPT { This->
Box(x); }
507 static void Construct(
MpObject* This, T x) NLIB_NOEXCEPT {
508 This->type_ = kUint64;
513 template <
class TR1_WORKAROUND>
514 struct MpObject::MyBox<float, FalseType, TR1_WORKAROUND> {
516 This->ReleaseIfNeeded();
517 This->type_ = kFloat;
523 switch (This->type_) {
528 *v =
static_cast<float>(This->via_.f64);
536 static void Assign(
MpObject* This,
float x) NLIB_NOEXCEPT { This->
Box(x); }
537 static void Construct(
MpObject* This,
float x) NLIB_NOEXCEPT {
538 This->type_ = kFloat;
543 template <
class TR1_WORKAROUND>
544 struct MpObject::MyBox<double, FalseType, TR1_WORKAROUND> {
546 This->ReleaseIfNeeded();
547 This->type_ = kDouble;
553 switch (This->type_) {
566 static void Assign(
MpObject* This,
double x) NLIB_NOEXCEPT { This->
Box(x); }
567 static void Construct(
MpObject* This,
double x) NLIB_NOEXCEPT {
568 This->type_ = kDouble;
573 template <
class STDSTRING>
574 struct MpObject::MyBox<STDSTRING, FalseType, FalseType> {
576 uint32_t n =
static_cast<uint32_t
>(str.size());
581 reinterpret_cast<const void*>(&str[0]),
591 NLIB_CATCH(std::bad_alloc&) {
return ENOMEM; }
596 template <
class T,
class ALLOC>
597 struct MpObject::MyBox<std::vector<T, ALLOC>, FalseType, FalseType> {
599 uint32_t n =
static_cast<uint32_t
>(vec.size());
604 for (uint32_t i = 0; i < n; ++i) {
605 e = (*tmp.via_.ary)[i].
Box(vec[i]);
614 NLIB_TRY { vec->resize(This->size_); }
615 NLIB_CATCH(std::bad_alloc&) {
return ENOMEM; }
616 for (uint32_t i = 0; i < This->size_; ++i) {
624 template <
class T,
class ALLOC>
625 struct MpObject::MyBox<Nlist<T, ALLOC>, FalseType, FalseType> {
627 size_t n = vec.
size();
632 for (
size_t i = 0; i < n; ++it, ++i) {
633 e = (*tmp.via_.ary)[i].
Box(*it);
644 for (uint32_t i = 0; i < This->size_; ++i) {
653 template <
class T1,
class T2>
654 struct MpObject::MyBox<std::pair<T1, T2>, FalseType, FalseType> {
659 e = (*tmp.via_.ary)[0].
Box(p.first);
661 e = (*tmp.via_.ary)[1].
Box(p.second);
671 e = (*This->via_.ary)[0].
Unbox(&p->first);
673 e = (*This->via_.ary)[1].
Unbox(&p->second);
679 #if defined(NLIB_CXX11_STDLIB_TUPLE) && defined(NLIB_CXX11_VARIADIC_TEMPLATES) 680 template <
class ...Args>
681 struct MpObject::MyBox<std::tuple<Args...>, FalseType, FalseType > {
683 template<
size_t N,
class HEAD>
685 return (*tmp->via_.ary)[N].Box(head);
687 template<
size_t N,
class HEAD,
class ...TAIL>
688 static errno_t BoxHelper(
MpObject* tmp,
const HEAD& head, TAIL&... tail) {
689 ErrnoT e = (*tmp->via_.ary)[N].
Box(head);
691 return BoxHelper<N + 1, TAIL...>(tmp, tail...);
693 template<
size_t N,
class HEAD>
695 return (*This->via_.ary)[N].Unbox(&head);
697 template<
size_t N,
class HEAD,
class ...TAIL>
698 static errno_t UnboxHelper(
const MpObject* This, HEAD& head, TAIL&... tail) {
701 return UnboxHelper<N + 1, TAIL...>(This, tail...);
703 template<
int ...>
struct seq {};
704 template<
int N,
int ...S>
struct gens : gens<N - 1, N - 1, S...> {};
706 struct gens<0, S...> {
707 typedef seq<S...> type;
711 return BoxHelper<0>(tmp, std::get<S>(p)...);
715 return UnboxHelper<0>(This, std::get<S>(p)...);
720 size_t count = std::tuple_size<std::tuple<Args...> >::value;
724 typedef typename gens<
sizeof...(Args)>::type MySeq;
725 e =
Box(&tmp, MySeq(), p);
733 if (
NLIB_UNLIKELY(This->size_ != std::tuple_size<std::tuple<Args...> >::value))
735 typedef typename gens<
sizeof...(Args)>::type MySeq;
736 return Unbox(This, MySeq(), *p);
741 template <
class K,
class V,
class Pr,
class Alloc>
742 struct MpObject::MyBox<std::map<K, V, Pr, Alloc>, FalseType, FalseType> {
744 typedef typename std::map<K, V, Pr, Alloc> maptype;
745 uint32_t n =
static_cast<uint32_t
>(m.size());
750 typename maptype::const_iterator it;
751 typename maptype::const_iterator it_end = m.end();
753 for (i = 0, it = m.begin(); it != it_end; ++it, ++i) {
767 for (uint32_t i = 0; i < This->size_; ++i) {
776 NLIB_TRY { (*m)[NLIB_MOVE(key)] = NLIB_MOVE(value); }
783 #ifdef NLIB_CXX11_STDLIB_UNORDERED 784 template <
class K,
class V,
class Hash,
class Pr,
class Alloc>
785 struct MpObject::MyBox<std::unordered_map<K, V, Hash, Pr, Alloc>, FalseType, FalseType > {
786 static errno_t Box(
MpObject* This,
const std::unordered_map<K, V, Hash, Pr, Alloc>& m) {
787 typedef typename std::unordered_map<K, V, Hash, Pr, Alloc> maptype;
788 uint32_t n =
static_cast<uint32_t
>(m.size());
793 typename maptype::const_iterator it;
794 typename maptype::const_iterator it_end = m.end();
796 for (i = 0, it = m.begin(); it != it_end; ++it, ++i) {
810 for (uint32_t i = 0; i < This->size_; ++i) {
819 NLIB_TRY { (*m)[NLIB_MOVE(key)] = NLIB_MOVE(value); }
829 return lhs.first == rhs.first && lhs.second == rhs.second;
832 return !(lhs == rhs);
835 return !(lhs == rhs);
838 template <u
int32_t n>
841 ErrnoT e = this->InitString(nn);
843 nlib_memcpy(this->GetString(), nn, reinterpret_cast<const void*>(&str[0]), nn);
847 template <
class T, u
int32_t n>
852 for (uint32_t i = 0; i < n; ++i) {
853 e = (*tmp.via_.ary)[i].
Box(vec[i]);
860 #ifdef NLIB_CXX11_STDLIB_ARRAY 861 template <
class T,
size_t n>
866 for (uint32_t i = 0; i < n; ++i) {
867 e = (*tmp.via_.ary)[i].
Box(vec[i]);
877 NLIB_EINVAL_IFNULL(a);
881 for (uint32_t i = 0; i < size_; ++i) {
891 NLIB_DEFINE_STD_SWAP(::nlib_ns::msgpack::MpObject)
892 NLIB_DEFINE_STD_SWAP(::nlib_ns::msgpack::MpObjectKv)
894 #if defined(_MSC_VER) && defined(nx_msgpack_EXPORTS) 895 #undef NLIB_VIS_PUBLIC 896 #define NLIB_VIS_PUBLIC NLIB_WINIMPORT 899 #endif // INCLUDE_NN_NLIB_MSGPACK_MPOBJECT_H_ nlib_utf8_t * GetString() noexcept
Gets a string from an object.
errno_t Unbox(T v) const
Unboxes the object.
bool IsString() const noexcept
Determines whether the stored value is a string.
bool IsMap() const noexcept
Determines whether the stored value is an associative array.
MpObject & operator[](size_t n)
For an array, returns a reference to an element of the array.
MpObjectKv() noexcept
Instantiates the object with default parameters (default constructor).
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
Prohibits use of the copy constructor and assignment operator for the class specified by TypeName...
Represents an unsigned integer type. The internal representation is uint64_t.
Represents an integer type. The internal representation is int64_t.
MpObject() noexcept
Instantiates the object with default parameters (default constructor). Set to the nil type...
~MpObject() noexcept
Destructor.
const void * GetExt(int8_t *tp, uint32_t *n) const noexcept
Gets an extended data type from an object.
Represents an array. The internal representation is an array of MpObject.
iterator begin() noexcept
Returns the iterator pointing to the beginning of the container.
const MpObject * GetArrayItem(size_t n) const noexcept
The same as GetArrayItem(size_t n).
MpObject * SwapArrayItem(size_t n, MpObject *obj) noexcept
Swaps the content of obj and the content of the object within an array.
const void * GetBinary(uint32_t *n) const noexcept
Gets binary from an object.
const nlib_utf8_t * GetString() const noexcept
Gets a string from an object.
MpObject * SwapMapItem(const nlib_utf8_t *key, MpObject *obj) noexcept
Swaps the content of obj and the content of the object within an associative array.
bool operator==(const HeapHash &rhs, const HeapHash &lhs)
Returns true if the two compared summaries are equal.
bool operator!=(const HeapHash &rhs, const HeapHash &lhs)
Returns true if the two compared summaries are not equal.
errno_t Box(const T &v)
Boxes the object.
BaseType::const_iterator const_iterator
Read-only forward iterator.
Object created when MessagePack or JSON is read.
Represents a floating point type. The internal representation is float.
pointer push_back()
Adds an element to the end and initializes it with the default constructor.
MpObject & operator=(const T &x)
The value is passed into MpObject.
MpObject second
Object used as a value.
Defines the class that resembles std::vector but can store objects that cannot be copied...
ObjectType
Data type of the object stored in MpObject.
bool IsExt() const noexcept
Determines whether the stored value is extended data.
errno_t InitArray(uint32_t n) noexcept
Initializes as an object with an n element array.
void clear() noexcept
Clears the container.
Represents a floating point type. The internal representation is double.
MpObject * SwapMapItem(const STDSTRING &key, MpObject *obj) noexcept
Swaps the content of obj and the content of the object within an associative array.
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.
void swap(MpObject &rhs) noexcept
Swaps the content of the object.
#define NLIB_CATCH(x)
Defines catch(x) if exceptions are enabled. If not, defines if (true).
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...
errno_t Box(const nlib_utf8_t *str) noexcept
Boxes the string.
#define NLIB_TRY
Defines try if exceptions are enabled. If not, defines if (true).
ObjectType GetType() const noexcept
Returns the object type.
bool IsArray() const noexcept
Determines whether the stored value is an array.
MpObject(const T &x)
The constructor for boxing a T-type object.
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
errno_t InitString(const nlib_utf8_t *str) noexcept
Initializes the object as a string.
errno_t Unbox(nlib_utf8_t(&str)[n]) const noexcept
See Unbox(T (&a)[n]).
const MpObject * GetMapItem(const STDSTRING &str) const noexcept
The same as GetMapItem(const STDSTRING& str).
A file that contains the configuration information for each development environment.
~MpObjectKv() noexcept
Destructor.
Represents a boolean type. The internal representation is a bool.
bool reserve(size_type n) noexcept
Allocates memory for n number of elements.
uint32_t GetSize() const noexcept
Returns the size of the array, associative array, string, or binary.
A container-like class similar to std::vector that can store objects that do not have copy constructo...
errno_t RemoveMapItem(const STDSTRING &str, MpObjectKv *kv) noexcept
Specifies a key and deletes the corresponding key and object in the associative array.
size_type size() const noexcept
Returns the number of stored elements.
Respresents a byte array (string).
bool IsBoolean() const noexcept
Determines whether the stored value is a boolean.
void * GetBinary(uint32_t *n) noexcept
Gets binary from an object.
Wraps functions like strlen and strcpy so they can be safely used.
void * GetExt(int8_t *tp, uint32_t *n) noexcept
Gets an extended data type from an object.
bool IsFloat() const noexcept
Determines whether the stored value is a single precision float.
MpObject first
Object used as a key.
#define NLIB_FINAL
Defines final if it is available for use. If not, holds an empty string.
MpObject * GetMapItem(const STDSTRING &str) noexcept
Specifies a string and gets the object in the associative array.
errno_t InitMap(uint32_t n) noexcept
Initializes the object as an n element associative array.
MpObject * GetArrayItem(size_t n) noexcept
Specifies an index and gets the object in the array.
bool IsDouble() const noexcept
Determines whether the stored value is a double.
A pair consisting of an MpObject-type key and value. Used to store an associative array...
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...
Class that corresponds to nil in MessagePack and null in JSON.
void swap(MpObjectKv &rhs) noexcept
Swaps the content of the object.
bool IsInteger() const noexcept
Determines whether the stored value is an integer.
bool IsBinary() const noexcept
Determines whether the stored value is binary.
Represents an associative array. The internal representation is an array of MpObject pairs...
errno_t Unbox(T(&a)[n]) const
Unboxes the object value.
errno_t Box(MpObject *obj, const T &v)
This function template can be specialized to define boxing the user type.