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_ 非負整数型を表します。内部表現は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)
この関数テンプレートを特殊化してユーザー型のボックス化を定義することが可能です。