3 #ifndef INCLUDE_NN_NLIB_MSGPACK_MPOBJECT_H_ 4 #define INCLUDE_NN_NLIB_MSGPACK_MPOBJECT_H_ 11 #include "nn/nlib/Swap.h" 15 #ifdef NLIB_CXX11_STDLIB_ARRAY 19 #ifdef NLIB_CXX11_STDLIB_UNORDERED 20 #include <unordered_map> 23 #ifdef NLIB_CXX11_STDLIB_TUPLE 27 #if defined(_MSC_VER) && defined(nx_msgpack_EXPORTS) 28 #undef NLIB_VIS_PUBLIC 29 #define NLIB_VIS_PUBLIC NLIB_WINEXPORT 98 return NLIB_LIKELY(0 == this->GetArrayItem(n, &obj)) ? obj : NULL;
102 return NLIB_LIKELY(0 == this->GetArrayItem(n, &obj)) ? obj : NULL;
105 NLIB_ASSERT(this->IsArray());
106 NLIB_ASSERT(n < size_);
107 return (*via_.ary)[n];
112 MpObject* GetMapItem(
const char (&str)[N]) NLIB_NOEXCEPT {
113 return GetMapItem(&str[0]);
116 const MpObject* GetMapItem(
const char (&str)[N])
const NLIB_NOEXCEPT {
117 return GetMapItem(&str[0]);
119 template<
class STDSTRING>
121 return GetMapItem(str.c_str());
123 template<
class STDSTRING>
125 return GetMapItem(str.c_str());
129 MpObject* p = this->GetArrayItem(n);
133 template<
class STDSTRING>
135 MpObject* p = this->GetMapItem(key);
141 return SwapMapItem(&str[0], obj);
144 MpObject* p = this->GetMapItem(str);
155 NLIB_MOVE_MEMBER_HELPER_1(
MpObject, type_);
160 MyBox<T, typename IsIntegral<T>::type,
typename IsSigned<T>::type>::Construct(
this, x);
167 if (type_ == STRING)
return via_.str;
168 if (
NLIB_LIKELY(type_ == STRING_INLINE))
return reinterpret_cast<char*
>(&raw14data_);
172 return const_cast<MpObject*
>(
this)->GetString();
175 if (type_ == BINARY) {
185 const void*
GetBinary(uint32_t* n)
const NLIB_NOEXCEPT {
186 return const_cast<MpObject*
>(
this)->GetBinary(n);
188 void*
GetExt(int8_t* tp, uint32_t* n) NLIB_NOEXCEPT {
191 *tp =
static_cast<int8_t
>(raw14data_);
197 const void*
GetExt(int8_t* tp, uint32_t* n)
const NLIB_NOEXCEPT {
198 return const_cast<MpObject*
>(
this)->GetExt(tp, n);
206 uint32_t n =
static_cast<uint32_t
>(
nlib_strlen(str));
207 return InitString(str, n);
216 template <u
int32_t n>
218 template <
class T, u
int32_t n>
220 #ifdef NLIB_CXX11_STDLIB_ARRAY 221 template <
class T,
size_t n>
226 return MyBox<T, typename IsIntegral<T>::type,
typename IsSigned<T>::type>
::Box(
this, v);
233 template <
class T,
size_t n>
235 return this->
Unbox(&a[0], n);
237 #ifdef NLIB_CXX11_STDLIB_ARRAY 238 template <
class T,
size_t n>
240 return this->
Unbox(reinterpret_cast<T*>(&*a.begin()), n);
245 return this->
Unbox(&str[0], n);
256 return MyBox<typename RemovePtr<T>::type,
257 typename IsIntegral<typename RemovePtr<T>::type>::type,
258 typename IsSigned<typename RemovePtr<T>::type>::type>
::Unbox(
this, v);
266 MyBox<T, typename IsIntegral<T>::type,
typename IsSigned<T>::type>::Assign(
this, x);
273 swap(type_, rhs.type_);
274 swap(raw14size_, rhs.raw14size_);
275 swap(raw14data_, rhs.raw14data_);
277 swap(size_, rhs.size_);
278 swap(via_.u64, rhs.via_.u64);
295 STRING_INLINE = 0x80 | STRING,
296 BINARY_INLINE = 0x80 | BINARY,
297 RAW_INLINE = 0x80 | RAW,
298 BOOLEAN_FALSE = 0x00 | BOOLEAN,
299 BOOLEAN_TRUE = 0x80 | BOOLEAN
305 if (type_ == STRING_INLINE || type_ == BINARY_INLINE)
310 bool IsNil() const NLIB_NOEXCEPT {
return GetType() == NIL; }
311 bool IsBoolean() const NLIB_NOEXCEPT {
return GetType() == BOOLEAN; }
314 return tp == UINT64 || tp == INT64;
316 bool IsFloat() const NLIB_NOEXCEPT {
return GetType() == FLOAT; }
317 bool IsDouble() const NLIB_NOEXCEPT {
return GetType() == DOUBLE; }
318 bool IsString() const NLIB_NOEXCEPT {
return GetType() == STRING; }
319 bool IsBinary() const NLIB_NOEXCEPT {
return GetType() == BINARY; }
320 bool IsExt() const NLIB_NOEXCEPT {
return GetType() == EXT; }
321 bool IsArray() const NLIB_NOEXCEPT {
return GetType() == ARRAY; }
322 bool IsMap() const NLIB_NOEXCEPT {
return GetType() == MAP; }
326 template <
class T,
class IS_INTEGRAL,
class IS_SIGNED>
330 if (!v)
return EINVAL;
333 static void Assign(
MpObject* This,
const T& x);
334 static void Construct(
MpObject* This,
const T& x);
336 void ReleaseIfNeeded() NLIB_NOEXCEPT {
337 if (type_ >= STRING && type_ <= EXT) ReleaseIfNeeded_();
359 NLIB_MOVE_MEMBER_HELPER_2(
MpObjectKv, first, second);
361 first.
swap(rhs.first);
362 second.
swap(rhs.second);
370 struct MpObject::MyBox<nil, FalseType, FalseType> {
373 This->ReleaseIfNeeded();
377 static void Assign(
MpObject* This, nil x) NLIB_NOEXCEPT { This->
Box(x); }
378 static void Construct(
MpObject* This, nil) NLIB_NOEXCEPT { This->type_ = NIL; }
382 struct MpObject::MyBox<bool, TrueType, FalseType> {
384 This->ReleaseIfNeeded();
385 This->type_ = v ?
static_cast<uint8_t
>(BOOLEAN_TRUE) : static_cast<uint8_t>(BOOLEAN_FALSE);
389 if (This->type_ == BOOLEAN_FALSE) {
392 }
else if (
NLIB_LIKELY(This->type_ == BOOLEAN_TRUE)) {
399 static void Assign(
MpObject* This,
bool x) NLIB_NOEXCEPT { This->
Box(x); }
400 static void Construct(
MpObject* This,
bool x) NLIB_NOEXCEPT {
401 This->type_ = x ?
static_cast<uint8_t
>(BOOLEAN_TRUE) : static_cast<uint8_t>(BOOLEAN_FALSE);
406 struct MpObject::MyBox<T, TrueType, TrueType> {
408 This->ReleaseIfNeeded();
415 if (This->type_ == INT64) {
416 *v =
static_cast<T
>(This->via_.i64);
419 *v =
static_cast<T
>(This->via_.u64);
425 static void Assign(
MpObject* This, T x) NLIB_NOEXCEPT { This->
Box(x); }
426 static void Construct(
MpObject* This, T x) NLIB_NOEXCEPT {
433 struct MpObject::MyBox<T, TrueType, FalseType> {
435 This->ReleaseIfNeeded();
436 This->type_ = UINT64;
442 if (This->type_ == INT64) {
443 *v =
static_cast<T
>(This->via_.i64);
446 *v =
static_cast<T
>(This->via_.u64);
452 static void Assign(
MpObject* This, T x) NLIB_NOEXCEPT { This->
Box(x); }
453 static void Construct(
MpObject* This, T x) NLIB_NOEXCEPT {
454 This->type_ = UINT64;
459 template <
class TR1_WORKAROUND>
460 struct MpObject::MyBox<float, FalseType, TR1_WORKAROUND> {
462 This->ReleaseIfNeeded();
469 switch (This->type_) {
474 *v =
static_cast<float>(This->via_.f64);
482 static void Assign(
MpObject* This,
float x) NLIB_NOEXCEPT { This->
Box(x); }
483 static void Construct(
MpObject* This,
float x) NLIB_NOEXCEPT {
489 template <
class TR1_WORKAROUND>
490 struct MpObject::MyBox<double, FalseType, TR1_WORKAROUND> {
492 This->ReleaseIfNeeded();
493 This->type_ = DOUBLE;
499 switch (This->type_) {
512 static void Assign(
MpObject* This,
double x) NLIB_NOEXCEPT { This->
Box(x); }
513 static void Construct(
MpObject* This,
double x) NLIB_NOEXCEPT {
514 This->type_ = DOUBLE;
519 template <
class STDSTRING>
520 struct MpObject::MyBox<STDSTRING, FalseType, FalseType> {
522 uint32_t n =
static_cast<uint32_t
>(str.size());
527 reinterpret_cast<const void*>(&str[0]),
537 NLIB_CATCH(std::bad_alloc&) {
return ENOMEM; }
542 template <
class T,
class ALLOC>
543 struct MpObject::MyBox<std::vector<T, ALLOC>, FalseType, FalseType> {
545 uint32_t n =
static_cast<uint32_t
>(vec.size());
550 for (uint32_t i = 0; i < n; ++i) {
551 e = (*tmp.via_.ary)[i].
Box(vec[i]);
560 NLIB_TRY { vec->resize(This->size_); }
561 NLIB_CATCH(std::bad_alloc&) {
return ENOMEM; }
562 for (uint32_t i = 0; i < This->size_; ++i) {
570 template <
class T,
class ALLOC>
571 struct MpObject::MyBox<Nlist<T, ALLOC>, FalseType, FalseType> {
573 size_t n = vec.
size();
578 for (
size_t i = 0; i < n; ++it, ++i) {
579 e = (*tmp.via_.ary)[i].
Box(*it);
590 for (uint32_t i = 0; i < This->size_; ++i) {
599 template <
class T1,
class T2>
600 struct MpObject::MyBox<std::pair<T1, T2>, FalseType, FalseType> {
605 e = (*tmp.via_.ary)[0].
Box(p.first);
607 e = (*tmp.via_.ary)[1].
Box(p.second);
617 e = (*This->via_.ary)[0].
Unbox(&p->first);
619 e = (*This->via_.ary)[1].
Unbox(&p->second);
625 #if defined(NLIB_CXX11_STDLIB_TUPLE) && defined(NLIB_CXX11_VARIADIC_TEMPLATES) 626 template <
class ...Args>
627 struct MpObject::MyBox<std::tuple<Args...>, FalseType, FalseType > {
629 template<
size_t N,
class HEAD>
631 return (*tmp->via_.ary)[N].Box(head);
633 template<
size_t N,
class HEAD,
class ...TAIL>
634 static errno_t BoxHelper(
MpObject* tmp,
const HEAD& head, TAIL&... tail) {
635 ErrnoT e = (*tmp->via_.ary)[N].
Box(head);
637 return BoxHelper<N + 1, TAIL...>(tmp, tail...);
639 template<
size_t N,
class HEAD>
641 return (*This->via_.ary)[N].Unbox(&head);
643 template<
size_t N,
class HEAD,
class ...TAIL>
644 static errno_t UnboxHelper(
const MpObject* This, HEAD& head, TAIL&... tail) {
647 return UnboxHelper<N + 1, TAIL...>(This, tail...);
649 template<
int ...>
struct seq {};
650 template<
int N,
int ...S>
struct gens : gens<N - 1, N - 1, S...> {};
652 struct gens<0, S...> {
653 typedef seq<S...> type;
657 return BoxHelper<0>(tmp, std::get<S>(p)...);
661 return UnboxHelper<0>(This, std::get<S>(p)...);
666 size_t count = std::tuple_size<std::tuple<Args...> >::value;
670 typedef typename gens<
sizeof...(Args)>::type MySeq;
671 e =
Box(&tmp, MySeq(), p);
679 if (
NLIB_UNLIKELY(This->size_ != std::tuple_size<std::tuple<Args...> >::value))
681 typedef typename gens<
sizeof...(Args)>::type MySeq;
682 return Unbox(This, MySeq(), *p);
687 template <
class K,
class V,
class Pr,
class Alloc>
688 struct MpObject::MyBox<std::map<K, V, Pr, Alloc>, FalseType, FalseType> {
690 typedef typename std::map<K, V, Pr, Alloc> maptype;
691 uint32_t n =
static_cast<uint32_t
>(m.size());
696 typename maptype::const_iterator it;
697 typename maptype::const_iterator it_end = m.end();
699 for (i = 0, it = m.begin(); it != it_end; ++it, ++i) {
713 for (uint32_t i = 0; i < This->size_; ++i) {
722 NLIB_TRY { (*m)[NLIB_MOVE(key)] = NLIB_MOVE(value); }
729 #ifdef NLIB_CXX11_STDLIB_UNORDERED 730 template <
class K,
class V,
class Hash,
class Pr,
class Alloc>
731 struct MpObject::MyBox<std::unordered_map<K, V, Hash, Pr, Alloc>, FalseType, FalseType > {
732 static errno_t Box(
MpObject* This,
const std::unordered_map<K, V, Hash, Pr, Alloc>& m) {
733 typedef typename std::unordered_map<K, V, Hash, Pr, Alloc> maptype;
734 uint32_t n =
static_cast<uint32_t
>(m.size());
739 typename maptype::const_iterator it;
740 typename maptype::const_iterator it_end = m.end();
742 for (i = 0, it = m.begin(); it != it_end; ++it, ++i) {
756 for (uint32_t i = 0; i < This->size_; ++i) {
765 NLIB_TRY { (*m)[NLIB_MOVE(key)] = NLIB_MOVE(value); }
775 return lhs.first == rhs.first && lhs.second == rhs.second;
778 return !(lhs == rhs);
781 return !(lhs == rhs);
784 template <u
int32_t n>
787 ErrnoT e = this->InitString(nn);
789 nlib_memcpy(this->GetString(), nn, reinterpret_cast<const void*>(&str[0]), nn);
793 template <
class T, u
int32_t n>
798 for (uint32_t i = 0; i < n; ++i) {
799 e = (*tmp.via_.ary)[i].
Box(vec[i]);
806 #ifdef NLIB_CXX11_STDLIB_ARRAY 807 template <
class T,
size_t n>
812 for (uint32_t i = 0; i < n; ++i) {
813 e = (*tmp.via_.ary)[i].
Box(vec[i]);
823 NLIB_EINVAL_IFNULL(a);
827 for (uint32_t i = 0; i < size_; ++i) {
837 NLIB_DEFINE_STD_SWAP(::nlib_ns::msgpack::MpObject)
838 NLIB_DEFINE_STD_SWAP(::nlib_ns::msgpack::MpObjectKv)
840 #if defined(_MSC_VER) && defined(nx_msgpack_EXPORTS) 841 #undef NLIB_VIS_PUBLIC 842 #define NLIB_VIS_PUBLIC NLIB_WINIMPORT 845 #endif // INCLUDE_NN_NLIB_MSGPACK_MPOBJECT_H_ Represents an unsigned integer type. The internal representation is uint64_t.
Represents an integer type. The internal representation is int64_t.
char * GetString() noexcept
Gets a string from an object.
Represents a floating point type. The internal representation is double.
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...
errno_t InitString(const char *str) noexcept
Initializes the object as a string.
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.
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 char * GetString() const noexcept
Gets a string from an object.
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.
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.
Represents an associative array. The internal representation is an array of MpObject pairs...
Represents an array. The internal representation is an array of MpObject.
errno_t InitArray(uint32_t n) noexcept
Initializes as an object with an n element array.
void clear() noexcept
Clears the container.
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...
#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.
errno_t Unbox(char(&str)[n]) const noexcept
See Unbox(T (&a)[n]).
MpObject(const T &x)
The constructor for boxing a T-type object.
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
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.
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...
size_type size() const noexcept
Returns the number of stored elements.
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.
MpObject * SwapMapItem(const char *str, MpObject *obj) noexcept
Swaps the content of obj and the content of the object within an 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...
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.
errno_t Box(const char *str) noexcept
Boxes the string.
Represents a boolean type. The internal representation is a bool.
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.
Represents a floating point type. The internal representation is float.