3 #ifndef INCLUDE_NN_NLIB_MSGPACK_MPOBJECT_H_
4 #define INCLUDE_NN_NLIB_MSGPACK_MPOBJECT_H_
12 #include "nn/nlib/Swap.h"
16 #ifdef NLIB_CXX11_STDLIB_ARRAY
20 #ifdef NLIB_CXX11_STDLIB_UNORDERED
21 #include <unordered_map>
24 #ifdef NLIB_CXX11_STDLIB_TUPLE
28 #if defined(_MSC_VER) && defined(nx_msgpack_EXPORTS)
29 #undef NLIB_VIS_PUBLIC
30 #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 < m_Size);
107 return (*m_Via.ary)[n];
115 MpObject* p = this->GetArrayItem(n);
121 MpObject* p = this->GetMapItem(key);
127 MpObject* p = this->GetMapItem(str);
131 MpObject* AppendArrayItem() NLIB_NOEXCEPT;
137 NLIB_MOVE_MEMBER_HELPER_1(
MpObject, m_Type);
142 MyBox<T, typename IsIntegral<T>::type,
typename IsSigned<T>::type>::Construct(
this, x);
151 if (m_Type == RAW)
return m_Via.raw;
152 if (
NLIB_LIKELY(m_Type == RAW_INLINE))
return &m_Raw14Data;
156 if (m_Type == RAW)
return m_Via.raw;
157 if (
NLIB_LIKELY(m_Type == RAW_INLINE))
return &m_Raw14Data;
167 template <u
int32_t n>
169 template <
class T, u
int32_t n>
171 #ifdef NLIB_CXX11_STDLIB_ARRAY
172 template <
class T,
size_t n>
177 return MyBox<T, typename IsIntegral<T>::type,
typename IsSigned<T>::type>
::Box(
this, v);
182 template <
class T,
size_t n>
184 return this->
Unbox(&a[0], n);
186 #ifdef NLIB_CXX11_STDLIB_ARRAY
187 template <
class T,
size_t n>
189 return this->
Unbox(reinterpret_cast<T*>(&*a.begin()), n);
194 return this->
Unbox(&str[0], n);
204 return MyBox<typename RemovePtr<T>::type,
205 typename IsIntegral<typename RemovePtr<T>::type>::type,
206 typename IsSigned<typename RemovePtr<T>::type>::type>
::Unbox(
this, v);
214 MyBox<T, typename IsIntegral<T>::type,
typename IsSigned<T>::type>::Assign(
this, x);
221 swap(m_Type, rhs.m_Type);
222 swap(m_Raw14Size, rhs.m_Raw14Size);
223 swap(m_Raw14Data, rhs.m_Raw14Data);
225 swap(m_Size, rhs.m_Size);
226 swap(m_Via.u64, rhs.m_Via.u64);
240 RAW_INLINE = 0x80 | RAW,
241 BOOLEAN_FALSE = 0x00 | BOOLEAN,
242 BOOLEAN_TRUE = 0x80 | BOOLEAN
245 return static_cast<ObjectType>(m_Type & 0x7F);
248 return (m_Type != RAW_INLINE) ? m_Size : m_Raw14Size;
250 bool IsNil() const NLIB_NOEXCEPT {
return GetType() == NIL; }
251 bool IsBoolean() const NLIB_NOEXCEPT {
return GetType() == BOOLEAN; }
254 return tp == UINT64 || tp == INT64;
256 bool IsFloat() const NLIB_NOEXCEPT {
return GetType() == FLOAT; }
257 bool IsDouble() const NLIB_NOEXCEPT {
return GetType() == DOUBLE; }
258 bool IsRaw() const NLIB_NOEXCEPT {
return GetType() == RAW; }
259 bool IsArray() const NLIB_NOEXCEPT {
return GetType() == ARRAY; }
260 bool IsMap() const NLIB_NOEXCEPT {
return GetType() == MAP; }
264 template <
class T,
class IS_INTEGRAL,
class IS_SIGNED>
268 if (!v)
return EINVAL;
271 static void Assign(MpObject* This,
const T& x);
272 static void Construct(MpObject* This,
const T& x);
274 void ReleaseIfNeeded() NLIB_NOEXCEPT {
275 if (m_Type >= RAW && m_Type <= MAP) ReleaseIfNeeded_();
277 void ReleaseIfNeeded_() NLIB_NOEXCEPT;
287 friend
NLIB_VIS_PUBLIC bool operator==(const MpObject& lhs, const MpObject& rhs);
297 NLIB_MOVE_MEMBER_HELPER_2(MpObjectKv, first, second);
298 void swap(MpObjectKv& rhs) NLIB_NOEXCEPT {
299 first.
swap(rhs.first);
300 second.
swap(rhs.second);
308 struct MpObject::MyBox<nil, FalseType, FalseType> {
309 static errno_t Box(MpObject* This, nil v) NLIB_NOEXCEPT {
311 This->ReleaseIfNeeded();
315 static void Assign(MpObject* This, nil x) NLIB_NOEXCEPT { This->Box(x); }
316 static void Construct(MpObject* This, nil) NLIB_NOEXCEPT { This->m_Type = NIL; }
320 struct MpObject::MyBox<bool, TrueType, FalseType> {
321 static errno_t Box(MpObject* This,
bool v) NLIB_NOEXCEPT {
322 This->ReleaseIfNeeded();
323 This->m_Type = v ?
static_cast<uint8_t
>(BOOLEAN_TRUE) : static_cast<uint8_t>(BOOLEAN_FALSE);
326 static errno_t Unbox(
const MpObject* This,
bool* v) NLIB_NOEXCEPT {
327 if (This->m_Type == BOOLEAN_FALSE) {
330 }
else if (
NLIB_LIKELY(This->m_Type == BOOLEAN_TRUE)) {
337 static void Assign(MpObject* This,
bool x) NLIB_NOEXCEPT { This->Box(x); }
338 static void Construct(MpObject* This,
bool x) NLIB_NOEXCEPT {
339 This->m_Type = x ?
static_cast<uint8_t
>(BOOLEAN_TRUE) : static_cast<uint8_t>(BOOLEAN_FALSE);
344 struct MpObject::MyBox<T, TrueType, TrueType> {
345 static errno_t Box(MpObject* This, T v) NLIB_NOEXCEPT {
346 This->ReleaseIfNeeded();
347 This->m_Type = INT64;
351 static errno_t Unbox(
const MpObject* This, T* v) NLIB_NOEXCEPT {
353 if (This->m_Type == INT64) {
354 *v =
static_cast<T
>(This->m_Via.i64);
357 *v =
static_cast<T
>(This->m_Via.u64);
363 static void Assign(MpObject* This, T x) NLIB_NOEXCEPT { This->Box(x); }
364 static void Construct(MpObject* This, T x) NLIB_NOEXCEPT {
365 This->m_Type = INT64;
371 struct MpObject::MyBox<T, TrueType, FalseType> {
372 static errno_t Box(MpObject* This, T v) NLIB_NOEXCEPT {
373 This->ReleaseIfNeeded();
374 This->m_Type = UINT64;
378 static errno_t Unbox(
const MpObject* This, T* v) NLIB_NOEXCEPT {
380 if (This->m_Type == INT64) {
381 *v =
static_cast<T
>(This->m_Via.i64);
384 *v =
static_cast<T
>(This->m_Via.u64);
390 static void Assign(MpObject* This, T x) NLIB_NOEXCEPT { This->Box(x); }
391 static void Construct(MpObject* This, T x) NLIB_NOEXCEPT {
392 This->m_Type = UINT64;
397 template <
class TR1_WORKAROUND>
398 struct MpObject::MyBox<float, FalseType, TR1_WORKAROUND> {
399 static errno_t Box(MpObject* This,
float v) NLIB_NOEXCEPT {
400 This->ReleaseIfNeeded();
401 This->m_Type = FLOAT;
405 static errno_t Unbox(
const MpObject* This,
float* v) NLIB_NOEXCEPT {
407 switch (This->m_Type) {
409 *v = This->m_Via.f32;
412 *v =
static_cast<float>(This->m_Via.f64);
420 static void Assign(MpObject* This,
float x) NLIB_NOEXCEPT { This->Box(x); }
421 static void Construct(MpObject* This,
float x) NLIB_NOEXCEPT {
422 This->m_Type = FLOAT;
427 template <
class TR1_WORKAROUND>
428 struct MpObject::MyBox<double, FalseType, TR1_WORKAROUND> {
429 static errno_t Box(MpObject* This,
double v) NLIB_NOEXCEPT {
430 This->ReleaseIfNeeded();
431 This->m_Type = DOUBLE;
435 static errno_t Unbox(
const MpObject* This,
double* v) NLIB_NOEXCEPT {
437 switch (This->m_Type) {
439 *v = This->m_Via.f32;
442 *v = This->m_Via.f64;
450 static void Assign(MpObject* This,
double x) NLIB_NOEXCEPT { This->Box(x); }
451 static void Construct(MpObject* This,
double x) NLIB_NOEXCEPT {
452 This->m_Type = DOUBLE;
458 struct MpObject::MyBox<
std::string, FalseType, FalseType> {
459 static errno_t Box(MpObject* This,
const std::string& str) NLIB_NOEXCEPT {
460 uint32_t n =
static_cast<uint32_t
>(str.size());
466 static errno_t Unbox(
const MpObject* This, std::string* str) NLIB_NOEXCEPT {
470 const char* chr =
reinterpret_cast<const char*
>(This->GetRaw());
471 NLIB_TRY { (*str).assign(chr, This->GetSize()); }
472 NLIB_CATCH(std::bad_alloc&) {
return ENOMEM; }
477 template <
class T,
class ALLOC>
478 struct MpObject::MyBox<
std::vector<T, ALLOC>, FalseType, FalseType> {
479 static errno_t Box(MpObject* This,
const std::vector<T, ALLOC>& vec) {
480 uint32_t n =
static_cast<uint32_t
>(vec.size());
485 for (uint32_t i = 0; i < n; ++i) {
486 e = (*tmp.m_Via.ary)[i].
Box(vec[i]);
492 static errno_t Unbox(
const MpObject* This, std::vector<T, ALLOC>* vec) {
495 NLIB_TRY { vec->resize(This->m_Size); }
496 NLIB_CATCH(std::bad_alloc&) {
return ENOMEM; }
497 for (uint32_t i = 0; i < This->m_Size; ++i) {
505 template <
class T,
class ALLOC>
506 struct MpObject::MyBox<Nlist<T, ALLOC>, FalseType, FalseType> {
507 static errno_t Box(MpObject* This,
const Nlist<T, ALLOC>& vec) {
508 size_t n = vec.size();
510 errno_t e = tmp.InitArray(static_cast<uint32_t>(n));
512 typename Nlist<T, ALLOC>::const_iterator it = vec.begin();
513 for (
size_t i = 0; i < n; ++it, ++i) {
514 e = (*tmp.m_Via.ary)[i].
Box(*it);
520 static errno_t Unbox(
const MpObject* This, Nlist<T, ALLOC>* vec) {
524 if (
NLIB_UNLIKELY(!vec->reserve(This->m_Size)))
return ENOMEM;
525 for (uint32_t i = 0; i < This->m_Size; ++i) {
526 T* item = vec->push_back();
534 template <
class T1,
class T2>
535 struct MpObject::MyBox<
std::pair<T1, T2>, FalseType, FalseType> {
536 static errno_t Box(MpObject* This,
const std::pair<T1, T2>& p) {
540 e = (*tmp.m_Via.ary)[0].
Box(p.first);
542 e = (*tmp.m_Via.ary)[1].
Box(p.second);
547 static errno_t Unbox(
const MpObject* This, std::pair<T1, T2>* p) {
552 e = (*This->m_Via.ary)[0].
Unbox(&p->first);
554 e = (*This->m_Via.ary)[1].
Unbox(&p->second);
560 #if defined(NLIB_CXX11_STDLIB_TUPLE) && defined(NLIB_CXX11_VARIADIC_TEMPLATES)
561 template <
class ...Args>
562 struct MpObject::MyBox<
std::tuple<Args...>, FalseType, FalseType > {
564 template<
size_t N,
class HEAD>
565 static errno_t BoxHelper(MpObject* tmp,
const HEAD& head) {
566 return (*tmp->m_Via.ary)[N].Box(head);
568 template<
size_t N,
class HEAD,
class ...TAIL>
569 static errno_t BoxHelper(MpObject* tmp,
const HEAD& head, TAIL&... tail) {
572 return BoxHelper<N + 1, TAIL...>(tmp, tail...);
574 template<
size_t N,
class HEAD>
575 static errno_t UnboxHelper(
const MpObject* This, HEAD& head) {
576 return (*This->m_Via.ary)[N].Unbox(&head);
578 template<
size_t N,
class HEAD,
class ...TAIL>
579 static errno_t UnboxHelper(
const MpObject* This, HEAD& head, TAIL&... tail) {
582 return UnboxHelper<N + 1, TAIL...>(This, tail...);
584 template<
int ...>
struct seq {};
585 template<
int N,
int ...S>
struct gens : gens<N - 1, N - 1, S...> {};
587 struct gens<0, S...> {
588 typedef seq<S...> type;
591 static errno_t Box(MpObject* tmp, seq<S...>,
const std::tuple<Args...>& p) {
592 return BoxHelper<0>(tmp, std::get<S>(p)...);
595 static errno_t Unbox(
const MpObject* This, seq<S...>, std::tuple<Args...>& p) {
596 return UnboxHelper<0>(This, std::get<S>(p)...);
600 static errno_t Box(MpObject* This,
const std::tuple<Args...>& p) {
601 size_t count = std::tuple_size<std::tuple<Args...> >::value;
603 errno_t e = tmp.InitArray(static_cast<uint32_t>(count));
605 typedef typename gens<
sizeof...(Args)>::type MySeq;
606 e =
Box(&tmp, MySeq(), p);
611 static errno_t Unbox(
const MpObject* This, std::tuple<Args...>* p) {
614 if (
NLIB_UNLIKELY(This->m_Size != std::tuple_size<std::tuple<Args...> >::value))
616 typedef typename gens<
sizeof...(Args)>::type MySeq;
617 return Unbox(This, MySeq(), *p);
622 template <
class K,
class V,
class Pr,
class Alloc>
623 struct MpObject::MyBox<
std::map<K, V, Pr, Alloc>, FalseType, FalseType> {
624 static errno_t Box(MpObject* This,
const std::map<K, V, Pr, Alloc>& m) {
625 typedef typename std::map<K, V, Pr, Alloc> maptype;
626 uint32_t n =
static_cast<uint32_t
>(m.size());
631 typename maptype::const_iterator it;
632 typename maptype::const_iterator it_end = m.end();
634 for (i = 0, it = m.begin(); it != it_end; ++it, ++i) {
635 MpObjectKv& kv = (*tmp.m_Via.mp)[i];
636 e = kv.first.Box(it->first);
638 e = kv.second.Box(it->second);
644 static errno_t Unbox(
const MpObject* This, std::map<K, V, Pr, Alloc>* m) {
648 for (uint32_t i = 0; i < This->m_Size; ++i) {
651 const MpObjectKv& kv = (*This->m_Via.mp)[i];
653 e = kv.first.Unbox(&key);
655 e = kv.second.Unbox(&value);
657 NLIB_TRY { (*m)[NLIB_MOVE(key)] = NLIB_MOVE(value); }
664 #ifdef NLIB_CXX11_STDLIB_UNORDERED
665 template <
class K,
class V,
class Hash,
class Pr,
class Alloc>
666 struct MpObject::MyBox<
std::unordered_map<K, V, Hash, Pr, Alloc>, FalseType, FalseType > {
667 static errno_t Box(MpObject* This,
const std::unordered_map<K, V, Hash, Pr, Alloc>& m) {
668 typedef typename std::unordered_map<K, V, Hash, Pr, Alloc> maptype;
669 uint32_t n =
static_cast<uint32_t
>(m.size());
674 typename maptype::const_iterator it;
675 typename maptype::const_iterator it_end = m.end();
677 for (i = 0, it = m.begin(); it != it_end; ++it, ++i) {
678 MpObjectKv& kv = (*tmp.m_Via.mp)[i];
679 e = kv.first.Box(it->first);
681 e = kv.second.Box(it->second);
687 static errno_t Unbox(
const MpObject* This, std::unordered_map<K, V, Hash, Pr, Alloc>* m) {
691 for (uint32_t i = 0; i < This->m_Size; ++i) {
694 const MpObjectKv& kv = (*This->m_Via.mp)[i];
696 e = kv.first.Unbox(&key);
698 e = kv.second.Unbox(&value);
700 NLIB_TRY { (*m)[NLIB_MOVE(key)] = NLIB_MOVE(value); }
710 return lhs.first == rhs.first && lhs.second == rhs.second;
713 return !(lhs == rhs);
716 return !(lhs == rhs);
719 template <u
int32_t n>
724 nlib_memcpy(this->GetRaw(), nn, reinterpret_cast<const void*>(&str[0]), nn);
728 template <
class T, u
int32_t n>
733 for (uint32_t i = 0; i < n; ++i) {
734 e = (*tmp.m_Via.ary)[i].
Box(vec[i]);
741 #ifdef NLIB_CXX11_STDLIB_ARRAY
742 template <
class T,
size_t n>
747 for (uint32_t i = 0; i < n; ++i) {
748 e = (*tmp.m_Via.ary)[i].
Box(vec[i]);
758 NLIB_EINVAL_IFNULL(a);
762 for (uint32_t i = 0; i < m_Size; ++i) {
772 NLIB_DEFINE_STD_SWAP(::nlib_ns::msgpack::MpObject)
773 NLIB_DEFINE_STD_SWAP(::
nlib_ns::msgpack::MpObjectKv)
775 #if defined(_MSC_VER) && defined(nx_msgpack_EXPORTS)
776 #undef NLIB_VIS_PUBLIC
777 #define NLIB_VIS_PUBLIC NLIB_WINIMPORT
780 #endif // INCLUDE_NN_NLIB_MSGPACK_MPOBJECT_H_
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
Represents an unsigned integer type. The internal representation is uint64_t.
Represents an integer type. The internal representation is int64_t.
Represents a floating point type. The internal representation is double.
uint32_t GetSize() const noexcept
Returns the size of the array, associative array, or Raw data (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_CATCH(x)
Defines catch(x) if exceptions are enabled. If not, defines if (true).
#define NLIB_FINAL
Defines final if it is available for use. If not, holds an empty string.
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
Prohibits use of the copy constructor and assignment operator for the class specified by TypeName...
bool IsArray() const noexcept
Determines whether the stored value is an array.
bool IsBoolean() const noexcept
Determines whether the stored value is a boolean.
~MpObject() noexcept
Destructor.
errno_t Unbox(char(&str)[n]) const noexcept
See Unbox(T (&a)[n]).
MpObject * SwapArrayItem(size_t n, MpObject *obj) noexcept
Swaps the content of obj and the content of the object within an array.
#define NLIB_TRY
Defines try if exceptions are enabled. If not, defines if (true).
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.
const void * GetRaw() const
The same as GetRaw.
Object created when MessagePack or JSON is read.
bool IsRaw() const noexcept
Determines whether the stored value is a byte string (character string).
Respresents a byte array (string).
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.
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.
errno_t Unbox(const MpObject *obj, T *v)
This function template can be specialized to define unboxing the user type.
void swap(MpObject &rhs) noexcept
Swaps the content of the object.
bool IsNil() const noexcept
Determines whether the stored value is nil.
Implements common features and features that are highly platform-dependent. Also refer to nlib Platfo...
MpObject * SwapMapItem(const std::string &key, MpObject *obj) noexcept
Swaps the content of obj and the content of the object within an associative array.
MpObject(const T &x)
The constructor for boxing a T-type object.
A file that contains the configuration information for each development environment.
~MpObjectKv() noexcept
Destructor.
bool IsInteger() const noexcept
Determines whether the stored value is an integer.
ObjectType GetType() const noexcept
Returns the object type.
A container-like class similar to std::vector that can store objects that do not have copy constructo...
errno_t Unbox(T v) const
Unboxes the object.
nlib_i64_t i64
nlib_i64_t is defined using typedef.
bool IsDouble() const noexcept
Determines whether the stored value is a double.
Wraps functions like strlen and strcpy so they can be safely used.
MpObject first
Object used as a key.
MpObject * SwapMapItem(const char *str, MpObject *obj) noexcept
Swaps the content of obj and the content of the object within an associative array.
MpObject * GetArrayItem(size_t n) noexcept
Specifies an index and gets the object in the array.
A pair consisting of an MpObject-type key and value. Used to store an associative array...
bool IsFloat() const noexcept
Determines whether the stored value is a single precision float.
Class that corresponds to nil in MessagePack and null in JSON.
void swap(MpObjectKv &rhs) noexcept
Swaps the content of the object.
errno_t Unbox(T(&a)[n]) const
Unboxes the object value.
void * GetRaw()
Gets the byte array from the object.
Represents a boolean type. The internal representation is a bool.
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.
const MpObject * GetArrayItem(size_t n) const noexcept
The same as GetArrayItem(size_t n).