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 111 return NLIB_LIKELY(0 == this->GetArrayItem(n, &obj)) ? obj : NULL;
115 return NLIB_LIKELY(0 == this->GetArrayItem(n, &obj)) ? obj : NULL;
118 NLIB_ASSERT(this->IsArray());
119 NLIB_ASSERT(n < size_);
120 return (*via_.ary)[n];
125 MpObject* GetMapItem(
const char (&str)[N]) NLIB_NOEXCEPT {
126 return GetMapItem(&str[0]);
129 const MpObject* GetMapItem(
const char (&str)[N])
const NLIB_NOEXCEPT {
130 return GetMapItem(&str[0]);
132 template<
class STDSTRING>
134 return GetMapItem(str.c_str());
136 template<
class STDSTRING>
138 return GetMapItem(str.c_str());
142 MpObject* p = this->GetArrayItem(n);
146 template<
class STDSTRING>
148 MpObject* p = this->GetMapItem(key);
154 return SwapMapItem(&str[0], obj);
157 MpObject* p = this->GetMapItem(str);
168 NLIB_MOVE_MEMBER_HELPER_1(
MpObject, type_);
173 MyBox<T, typename IsIntegral<T>::type,
typename IsSigned<T>::type>::Construct(
this, x);
180 if (type_ == STRING)
return via_.str;
181 if (
NLIB_LIKELY(type_ == STRING_INLINE))
return reinterpret_cast<char*
>(&raw14data_);
185 return const_cast<MpObject*
>(
this)->GetString();
188 if (type_ == BINARY) {
198 const void*
GetBinary(uint32_t* n)
const NLIB_NOEXCEPT {
199 return const_cast<MpObject*
>(
this)->GetBinary(n);
201 void*
GetExt(int8_t* tp, uint32_t* n) NLIB_NOEXCEPT {
204 *tp =
static_cast<int8_t
>(raw14data_);
210 const void*
GetExt(int8_t* tp, uint32_t* n)
const NLIB_NOEXCEPT {
211 return const_cast<MpObject*
>(
this)->GetExt(tp, n);
219 uint32_t n =
static_cast<uint32_t
>(
nlib_strlen(str));
220 return InitString(str, n);
229 template <u
int32_t n>
231 template <
class T, u
int32_t n>
233 #ifdef NLIB_CXX11_STDLIB_ARRAY 234 template <
class T,
size_t n>
239 return MyBox<T, typename IsIntegral<T>::type,
typename IsSigned<T>::type>
::Box(
this, v);
246 template <
class T,
size_t n>
248 return this->
Unbox(&a[0], n);
250 #ifdef NLIB_CXX11_STDLIB_ARRAY 251 template <
class T,
size_t n>
253 return this->
Unbox(reinterpret_cast<T*>(&*a.begin()), n);
258 return this->
Unbox(&str[0], n);
269 return MyBox<typename RemovePtr<T>::type,
270 typename IsIntegral<typename RemovePtr<T>::type>::type,
271 typename IsSigned<typename RemovePtr<T>::type>::type>
::Unbox(
this, v);
279 MyBox<T, typename IsIntegral<T>::type,
typename IsSigned<T>::type>::Assign(
this, x);
286 swap(type_, rhs.type_);
287 swap(raw14size_, rhs.raw14size_);
288 swap(raw14data_, rhs.raw14data_);
290 swap(size_, rhs.size_);
291 swap(via_.u64, rhs.via_.u64);
308 STRING_INLINE = 0x80 | STRING,
309 BINARY_INLINE = 0x80 | BINARY,
310 RAW_INLINE = 0x80 | RAW,
311 BOOLEAN_FALSE = 0x00 | BOOLEAN,
312 BOOLEAN_TRUE = 0x80 | BOOLEAN
318 if (type_ == STRING_INLINE || type_ == BINARY_INLINE)
323 bool IsNil() const NLIB_NOEXCEPT {
return GetType() == NIL; }
324 bool IsBoolean() const NLIB_NOEXCEPT {
return GetType() == BOOLEAN; }
327 return tp == UINT64 || tp == INT64;
329 bool IsFloat() const NLIB_NOEXCEPT {
return GetType() == FLOAT; }
330 bool IsDouble() const NLIB_NOEXCEPT {
return GetType() == DOUBLE; }
331 bool IsString() const NLIB_NOEXCEPT {
return GetType() == STRING; }
332 bool IsBinary() const NLIB_NOEXCEPT {
return GetType() == BINARY; }
333 bool IsExt() const NLIB_NOEXCEPT {
return GetType() == EXT; }
334 bool IsArray() const NLIB_NOEXCEPT {
return GetType() == ARRAY; }
335 bool IsMap() const NLIB_NOEXCEPT {
return GetType() == MAP; }
339 template <
class T,
class IS_INTEGRAL,
class IS_SIGNED>
343 if (!v)
return EINVAL;
346 static void Assign(
MpObject* This,
const T& x);
347 static void Construct(
MpObject* This,
const T& x);
349 void ReleaseIfNeeded() NLIB_NOEXCEPT {
350 if (type_ >= STRING && type_ <= EXT) ReleaseIfNeeded_();
372 NLIB_MOVE_MEMBER_HELPER_2(
MpObjectKv, first, second);
374 first.
swap(rhs.first);
375 second.
swap(rhs.second);
383 struct MpObject::MyBox<nil, FalseType, FalseType> {
386 This->ReleaseIfNeeded();
390 static void Assign(
MpObject* This, nil x) NLIB_NOEXCEPT { This->
Box(x); }
391 static void Construct(
MpObject* This, nil) NLIB_NOEXCEPT { This->type_ = NIL; }
395 struct MpObject::MyBox<bool, TrueType, FalseType> {
397 This->ReleaseIfNeeded();
398 This->type_ = v ?
static_cast<uint8_t
>(BOOLEAN_TRUE) : static_cast<uint8_t>(BOOLEAN_FALSE);
402 if (This->type_ == BOOLEAN_FALSE) {
405 }
else if (
NLIB_LIKELY(This->type_ == BOOLEAN_TRUE)) {
412 static void Assign(
MpObject* This,
bool x) NLIB_NOEXCEPT { This->
Box(x); }
413 static void Construct(
MpObject* This,
bool x) NLIB_NOEXCEPT {
414 This->type_ = x ?
static_cast<uint8_t
>(BOOLEAN_TRUE) : static_cast<uint8_t>(BOOLEAN_FALSE);
419 struct MpObject::MyBox<T, TrueType, TrueType> {
421 This->ReleaseIfNeeded();
428 if (This->type_ == INT64) {
429 *v =
static_cast<T
>(This->via_.i64);
432 *v =
static_cast<T
>(This->via_.u64);
438 static void Assign(
MpObject* This, T x) NLIB_NOEXCEPT { This->
Box(x); }
439 static void Construct(
MpObject* This, T x) NLIB_NOEXCEPT {
446 struct MpObject::MyBox<T, TrueType, FalseType> {
448 This->ReleaseIfNeeded();
449 This->type_ = UINT64;
455 if (This->type_ == INT64) {
456 *v =
static_cast<T
>(This->via_.i64);
459 *v =
static_cast<T
>(This->via_.u64);
465 static void Assign(
MpObject* This, T x) NLIB_NOEXCEPT { This->
Box(x); }
466 static void Construct(
MpObject* This, T x) NLIB_NOEXCEPT {
467 This->type_ = UINT64;
472 template <
class TR1_WORKAROUND>
473 struct MpObject::MyBox<float, FalseType, TR1_WORKAROUND> {
475 This->ReleaseIfNeeded();
482 switch (This->type_) {
487 *v =
static_cast<float>(This->via_.f64);
495 static void Assign(
MpObject* This,
float x) NLIB_NOEXCEPT { This->
Box(x); }
496 static void Construct(
MpObject* This,
float x) NLIB_NOEXCEPT {
502 template <
class TR1_WORKAROUND>
503 struct MpObject::MyBox<double, FalseType, TR1_WORKAROUND> {
505 This->ReleaseIfNeeded();
506 This->type_ = DOUBLE;
512 switch (This->type_) {
525 static void Assign(
MpObject* This,
double x) NLIB_NOEXCEPT { This->
Box(x); }
526 static void Construct(
MpObject* This,
double x) NLIB_NOEXCEPT {
527 This->type_ = DOUBLE;
532 template <
class STDSTRING>
533 struct MpObject::MyBox<STDSTRING, FalseType, FalseType> {
535 uint32_t n =
static_cast<uint32_t
>(str.size());
540 reinterpret_cast<const void*>(&str[0]),
550 NLIB_CATCH(std::bad_alloc&) {
return ENOMEM; }
555 template <
class T,
class ALLOC>
556 struct MpObject::MyBox<std::vector<T, ALLOC>, FalseType, FalseType> {
558 uint32_t n =
static_cast<uint32_t
>(vec.size());
563 for (uint32_t i = 0; i < n; ++i) {
564 e = (*tmp.via_.ary)[i].
Box(vec[i]);
573 NLIB_TRY { vec->resize(This->size_); }
574 NLIB_CATCH(std::bad_alloc&) {
return ENOMEM; }
575 for (uint32_t i = 0; i < This->size_; ++i) {
583 template <
class T,
class ALLOC>
584 struct MpObject::MyBox<Nlist<T, ALLOC>, FalseType, FalseType> {
586 size_t n = vec.
size();
591 for (
size_t i = 0; i < n; ++it, ++i) {
592 e = (*tmp.via_.ary)[i].
Box(*it);
603 for (uint32_t i = 0; i < This->size_; ++i) {
612 template <
class T1,
class T2>
613 struct MpObject::MyBox<std::pair<T1, T2>, FalseType, FalseType> {
618 e = (*tmp.via_.ary)[0].
Box(p.first);
620 e = (*tmp.via_.ary)[1].
Box(p.second);
630 e = (*This->via_.ary)[0].
Unbox(&p->first);
632 e = (*This->via_.ary)[1].
Unbox(&p->second);
638 #if defined(NLIB_CXX11_STDLIB_TUPLE) && defined(NLIB_CXX11_VARIADIC_TEMPLATES) 639 template <
class ...Args>
640 struct MpObject::MyBox<std::tuple<Args...>, FalseType, FalseType > {
642 template<
size_t N,
class HEAD>
644 return (*tmp->via_.ary)[N].Box(head);
646 template<
size_t N,
class HEAD,
class ...TAIL>
647 static errno_t BoxHelper(
MpObject* tmp,
const HEAD& head, TAIL&... tail) {
648 ErrnoT e = (*tmp->via_.ary)[N].
Box(head);
650 return BoxHelper<N + 1, TAIL...>(tmp, tail...);
652 template<
size_t N,
class HEAD>
654 return (*This->via_.ary)[N].Unbox(&head);
656 template<
size_t N,
class HEAD,
class ...TAIL>
657 static errno_t UnboxHelper(
const MpObject* This, HEAD& head, TAIL&... tail) {
660 return UnboxHelper<N + 1, TAIL...>(This, tail...);
662 template<
int ...>
struct seq {};
663 template<
int N,
int ...S>
struct gens : gens<N - 1, N - 1, S...> {};
665 struct gens<0, S...> {
666 typedef seq<S...> type;
670 return BoxHelper<0>(tmp, std::get<S>(p)...);
674 return UnboxHelper<0>(This, std::get<S>(p)...);
679 size_t count = std::tuple_size<std::tuple<Args...> >::value;
683 typedef typename gens<
sizeof...(Args)>::type MySeq;
684 e =
Box(&tmp, MySeq(), p);
692 if (
NLIB_UNLIKELY(This->size_ != std::tuple_size<std::tuple<Args...> >::value))
694 typedef typename gens<
sizeof...(Args)>::type MySeq;
695 return Unbox(This, MySeq(), *p);
700 template <
class K,
class V,
class Pr,
class Alloc>
701 struct MpObject::MyBox<std::map<K, V, Pr, Alloc>, FalseType, FalseType> {
703 typedef typename std::map<K, V, Pr, Alloc> maptype;
704 uint32_t n =
static_cast<uint32_t
>(m.size());
709 typename maptype::const_iterator it;
710 typename maptype::const_iterator it_end = m.end();
712 for (i = 0, it = m.begin(); it != it_end; ++it, ++i) {
726 for (uint32_t i = 0; i < This->size_; ++i) {
735 NLIB_TRY { (*m)[NLIB_MOVE(key)] = NLIB_MOVE(value); }
742 #ifdef NLIB_CXX11_STDLIB_UNORDERED 743 template <
class K,
class V,
class Hash,
class Pr,
class Alloc>
744 struct MpObject::MyBox<std::unordered_map<K, V, Hash, Pr, Alloc>, FalseType, FalseType > {
745 static errno_t Box(
MpObject* This,
const std::unordered_map<K, V, Hash, Pr, Alloc>& m) {
746 typedef typename std::unordered_map<K, V, Hash, Pr, Alloc> maptype;
747 uint32_t n =
static_cast<uint32_t
>(m.size());
752 typename maptype::const_iterator it;
753 typename maptype::const_iterator it_end = m.end();
755 for (i = 0, it = m.begin(); it != it_end; ++it, ++i) {
769 for (uint32_t i = 0; i < This->size_; ++i) {
778 NLIB_TRY { (*m)[NLIB_MOVE(key)] = NLIB_MOVE(value); }
788 return lhs.first == rhs.first && lhs.second == rhs.second;
791 return !(lhs == rhs);
794 return !(lhs == rhs);
797 template <u
int32_t n>
800 ErrnoT e = this->InitString(nn);
802 nlib_memcpy(this->GetString(), nn, reinterpret_cast<const void*>(&str[0]), nn);
806 template <
class T, u
int32_t n>
811 for (uint32_t i = 0; i < n; ++i) {
812 e = (*tmp.via_.ary)[i].
Box(vec[i]);
819 #ifdef NLIB_CXX11_STDLIB_ARRAY 820 template <
class T,
size_t n>
825 for (uint32_t i = 0; i < n; ++i) {
826 e = (*tmp.via_.ary)[i].
Box(vec[i]);
836 NLIB_EINVAL_IFNULL(a);
840 for (uint32_t i = 0; i < size_; ++i) {
850 NLIB_DEFINE_STD_SWAP(::nlib_ns::msgpack::MpObject)
851 NLIB_DEFINE_STD_SWAP(::nlib_ns::msgpack::MpObjectKv)
853 #if defined(_MSC_VER) && defined(nx_msgpack_EXPORTS) 854 #undef NLIB_VIS_PUBLIC 855 #define NLIB_VIS_PUBLIC NLIB_WINIMPORT 858 #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.