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_ 非負整数型を表します。内部表現はuint64_tです。
char * GetString() noexcept
オブジェクトから文字列を取得します。
浮動小数型を表します。内部表現はdoubleです。
errno_t Unbox(T v) const
オブジェクトをアンボックス化します。
bool IsString() const noexcept
格納されている値が文字列であるかどうかを調べます。
bool IsMap() const noexcept
格納されている値が連想配列であるかどうかを調べます。
MpObject & operator[](size_t n)
配列である場合に配列の要素への参照を返します。
MpObjectKv() noexcept
デフォルトコンストラクタです。
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
TypeName で指定されたクラスのコピーコンストラクタと代入演算子を禁止します。
errno_t InitString(const char *str) noexcept
オブジェクトを文字列として初期化します。
MpObject() noexcept
デフォルトコンストラクタです。nil型に設定されます。
~MpObject() noexcept
デストラクタです。
const void * GetExt(int8_t *tp, uint32_t *n) const noexcept
オブジェクトから拡張データ型を取得します。
iterator begin() noexcept
コンテナの先頭を指す反復子を返します。
const MpObject * GetArrayItem(size_t n) const noexcept
GetArrayItem(size_t n) と同様です。
MpObject * SwapArrayItem(size_t n, MpObject *obj) noexcept
obj の内容と配列内のオブジェクトの内容を交換します。
const void * GetBinary(uint32_t *n) const noexcept
オブジェクトからバイナリを取得します。
const char * GetString() const noexcept
オブジェクトから文字列を取得します。
bool operator==(const HeapHash &rhs, const HeapHash &lhs)
2つのサマリを比較して等価ならば、trueを返します。
bool operator!=(const HeapHash &rhs, const HeapHash &lhs)
2つのサマリを比較して等価でなければ、trueを返します。
errno_t Box(const T &v)
オブジェクトをボックス化します。
BaseType::const_iterator const_iterator
読み取り専用フォワードイテレータ
MessagePack又はJSONを読み込むことで作成されるオブジェクトです。
pointer push_back()
末尾に要素を追加してデフォルトコンストラクタで初期化します。
MpObject & operator=(const T &x)
値をMpObjectに代入します。
MpObject second
値となるオブジェクトです。
std::vectorに似ていますが、コピーできないオブジェクトを格納可能なクラスが定義されています。 ...
ObjectType
MpObjectに格納されているオブジェクトの型情報です。
bool IsExt() const noexcept
格納されている値が拡張データであるかどうかを調べます。
連想配列を表します。内部ではMpObjectのペアの列として表現されています。
配列を表します。内部ではMpObjectの列として表現されています。
errno_t InitArray(uint32_t n) noexcept
オブジェクトをn 個の要素を持つ配列として初期化します。
void clear() noexcept
コンテナをクリアします。
MpObject * SwapMapItem(const STDSTRING &key, MpObject *obj) noexcept
obj の内容と連想配列内のオブジェクトの内容を交換します。
errno_t Unbox(const MpObject *obj, T *v)
この関数テンプレートを特殊化してユーザー型のアンボックス化を定義することが可能です。 ...
bool IsNil() const noexcept
格納されている値ががnilであるかどうかを調べます。
void swap(MpObject &rhs) noexcept
オブジェクトの中身をスワップします。
#define NLIB_CATCH(x)
例外が有効なときはcatch(x), そうでなければif (true)が定義されます。
errno_t InitString(uint32_t n) noexcept
オブジェクトを文字列として初期化します。
errno_tをラップするクラスです。Visual Studioのデバッガ上での表示を改善します。
#define NLIB_TRY
例外が有効なときはtry, そうでなければif (true)が定義されます。
ObjectType GetType() const noexcept
オブジェクトの型を返します。
bool IsArray() const noexcept
格納されている値が配列であるかどうかを調べます。
errno_t Unbox(char(&str)[n]) const noexcept
Unbox(T (&a)[n]) を御覧ください。
MpObject(const T &x)
T型のオブジェクトをボックス化するコンストラクタです。
#define NLIB_NOEXCEPT
環境に合わせてnoexcept 又は同等の定義がされます。
const MpObject * GetMapItem(const STDSTRING &str) const noexcept
GetMapItem(const STDSTRING& str) と同様です。
~MpObjectKv() noexcept
デストラクタです。
bool reserve(size_type n) noexcept
n 個の要素のためのメモリをアロケート済みにします。
uint32_t GetSize() const noexcept
配列や連想配列や文字列やバイナリの場合にそのサイズを返します。
std::vectorに似た、コピーコンストラクタを持たないオブジェクトを格納可能なコンテナ類似クラスです。 ...
size_type size() const noexcept
格納されている要素の個数を返します。
bool IsBoolean() const noexcept
格納されている値が真偽値であるかどうかを調べます。
void * GetBinary(uint32_t *n) noexcept
オブジェクトからバイナリを取得します。
strlen, strcpy等を安全に使えるようにラップしています。
void * GetExt(int8_t *tp, uint32_t *n) noexcept
オブジェクトから拡張データ型を取得します。
bool IsFloat() const noexcept
格納されている値が単精度浮動小数点型であるかどうかを調べます。
MpObject first
キーとなるオブジェクトです。
#define NLIB_FINAL
利用可能であればfinalが定義されます。そうでない場合は空文字列です。
MpObject * GetMapItem(const STDSTRING &str) noexcept
文字列を指定して連想配列内のオブジェクトを取得します。
MpObject * SwapMapItem(const char *str, MpObject *obj) noexcept
obj の内容と連想配列内のオブジェクトの内容を交換します。
errno_t InitMap(uint32_t n) noexcept
オブジェクトをn個の要素を持つ連想配列として初期化します。
MpObject * GetArrayItem(size_t n) noexcept
インデックスを指定して配列内のオブジェクトを取得します。
bool IsDouble() const noexcept
格納されている値が倍精度浮動小数点型であるかどうかを調べます。
MpObject型のキーと値のペアです。連想配列を格納するために利用されます。
MessagePackのnil, 及びJSONのnullに対応するクラスです。
void swap(MpObjectKv &rhs) noexcept
オブジェクトの中身をスワップします。
bool IsInteger() const noexcept
格納されている値が整数値であるかどうかを調べます。
bool IsBinary() const noexcept
格納されている値がバイナリであるかどうかを調べます。
errno_t Box(const char *str) noexcept
文字列をボックス化します。
errno_t Unbox(T(&a)[n]) const
オブジェクトの値をアンボックス化します。
errno_t Box(MpObject *obj, const T &v)
この関数テンプレートを特殊化してユーザー型のボックス化を定義することが可能です。