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 117 return NLIB_LIKELY(0 == this->GetArrayItem(n, &obj)) ? obj : NULL;
121 return NLIB_LIKELY(0 == this->GetArrayItem(n, &obj)) ? obj : NULL;
124 NLIB_ASSERT(this->IsArray());
125 NLIB_ASSERT(n < size_);
126 return (*via_.ary)[n];
132 return GetMapItem(&str[0]);
136 return GetMapItem(&str[0]);
138 template<
class STDSTRING>
140 return GetMapItem(&str[0], str.size());
142 template<
class STDSTRING>
144 return GetMapItem(&str[0], str.size());
148 MpObject* p = this->GetArrayItem(n);
152 template<
class STDSTRING>
154 MpObject* p = this->GetMapItem(key);
160 return SwapMapItem(&key[0], obj);
163 MpObject* p = this->GetMapItem(key);
175 NLIB_MOVE_MEMBER_HELPER_1(
MpObject, type_);
180 MyBox<T, typename IsIntegral<T>::type,
typename IsSigned<T>::type>::Construct(
this, x);
187 MpObjectKv** obj) NLIB_NOEXCEPT NLIB_NONNULL {
189 errno_t e = this->GetMapItem(str, n, &kv);
190 if (e != 0)
return e;
197 if (type_ == kString)
return via_.str;
199 return reinterpret_cast<nlib_utf8_t*
>(&raw14data_);
205 template<
class STDSTRING>
207 return RemoveMapItem(str.c_str(), kv);
211 return const_cast<MpObject*
>(
this)->GetString();
214 if (type_ == kBinary) {
224 const void*
GetBinary(uint32_t* n)
const NLIB_NOEXCEPT {
225 return const_cast<MpObject*
>(
this)->GetBinary(n);
227 void*
GetExt(int8_t* tp, uint32_t* n) NLIB_NOEXCEPT {
230 *tp =
static_cast<int8_t
>(raw14data_);
236 const void*
GetExt(int8_t* tp, uint32_t* n)
const NLIB_NOEXCEPT {
237 return const_cast<MpObject*
>(
this)->GetExt(tp, n);
245 uint32_t n =
static_cast<uint32_t
>(
nlib_strlen(str));
246 return InitString(str, n);
255 template <u
int32_t n>
257 template <
class T, u
int32_t n>
259 #ifdef NLIB_CXX11_STDLIB_ARRAY 260 template <
class T,
size_t n>
265 return MyBox<T, typename IsIntegral<T>::type,
typename IsSigned<T>::type>
::Box(
this, v);
272 template <
class T,
size_t n>
274 return this->
Unbox(&a[0], n);
276 #ifdef NLIB_CXX11_STDLIB_ARRAY 277 template <
class T,
size_t n>
279 return this->
Unbox(reinterpret_cast<T*>(&*a.begin()), n);
284 return this->
Unbox(&str[0], n);
295 return MyBox<typename RemovePtr<T>::type,
296 typename IsIntegral<typename RemovePtr<T>::type>::type,
297 typename IsSigned<typename RemovePtr<T>::type>::type>
::Unbox(
this, v);
305 MyBox<T, typename IsIntegral<T>::type,
typename IsSigned<T>::type>::Assign(
this, x);
309 MpObject* Clone() NLIB_NOEXCEPT
const;
312 swap(type_, rhs.type_);
313 swap(raw14size_, rhs.raw14size_);
314 swap(raw14data_, rhs.raw14data_);
316 swap(size_, rhs.size_);
317 swap(via_.u64, rhs.via_.u64);
333 kStringInline = 0x80 | kString,
334 kBinaryInline = 0x80 | kBinary,
335 kBooleanFalse = 0x00 | kBoolean,
336 kBooleanTrue = 0x80 | kBoolean,
349 STRING_INLINE = kStringInline,
350 BINARY_INLINE = kBinaryInline,
351 RAW_INLINE = 0x80 | RAW,
352 BOOLEAN_FALSE = kBooleanFalse,
353 BOOLEAN_TRUE = kBooleanTrue
359 if (type_ == kStringInline || type_ == kBinaryInline)
364 bool IsNil() const NLIB_NOEXCEPT {
return GetType() == kNil; }
365 bool IsBoolean() const NLIB_NOEXCEPT {
return GetType() == kBoolean; }
368 return tp == kUint64 || tp == kInt64;
370 bool IsFloat() const NLIB_NOEXCEPT {
return GetType() == kFloat; }
371 bool IsDouble() const NLIB_NOEXCEPT {
return GetType() == kDouble; }
372 bool IsString() const NLIB_NOEXCEPT {
return GetType() == kString; }
373 bool IsBinary() const NLIB_NOEXCEPT {
return GetType() == kBinary; }
374 bool IsExt() const NLIB_NOEXCEPT {
return GetType() == kExt; }
375 bool IsArray() const NLIB_NOEXCEPT {
return GetType() == kArray; }
376 bool IsMap() const NLIB_NOEXCEPT {
return GetType() == kMap; }
380 template <
class T,
class IS_INTEGRAL,
class IS_SIGNED>
384 if (!v)
return EINVAL;
387 static void Assign(
MpObject* This,
const T& x);
388 static void Construct(
MpObject* This,
const T& x);
390 void ReleaseIfNeeded() NLIB_NOEXCEPT {
391 if (type_ >= kString && type_ <= kExt) ReleaseIfNeeded_();
413 NLIB_MOVE_MEMBER_HELPER_2(
MpObjectKv, first, second);
415 first.
swap(rhs.first);
416 second.
swap(rhs.second);
424 struct MpObject::MyBox<nil, FalseType, FalseType> {
427 This->ReleaseIfNeeded();
431 static void Assign(
MpObject* This, nil x) NLIB_NOEXCEPT { This->
Box(x); }
432 static void Construct(
MpObject* This, nil) NLIB_NOEXCEPT { This->type_ = kNil; }
436 struct MpObject::MyBox<bool, TrueType, FalseType> {
438 This->ReleaseIfNeeded();
439 This->type_ = v ?
static_cast<uint8_t
>(kBooleanTrue) : static_cast<uint8_t>(kBooleanFalse);
443 if (This->type_ == kBooleanFalse) {
446 }
else if (
NLIB_LIKELY(This->type_ == kBooleanTrue)) {
453 static void Assign(
MpObject* This,
bool x) NLIB_NOEXCEPT { This->
Box(x); }
454 static void Construct(
MpObject* This,
bool x) NLIB_NOEXCEPT {
455 This->type_ = x ?
static_cast<uint8_t
>(kBooleanTrue) : static_cast<uint8_t>(kBooleanFalse);
460 struct MpObject::MyBox<T, TrueType, TrueType> {
462 This->ReleaseIfNeeded();
463 This->type_ = kInt64;
469 if (This->type_ == kInt64) {
470 *v =
static_cast<T
>(This->via_.i64);
473 *v =
static_cast<T
>(This->via_.u64);
479 static void Assign(
MpObject* This, T x) NLIB_NOEXCEPT { This->
Box(x); }
480 static void Construct(
MpObject* This, T x) NLIB_NOEXCEPT {
481 This->type_ = kInt64;
487 struct MpObject::MyBox<T, TrueType, FalseType> {
489 This->ReleaseIfNeeded();
490 This->type_ = kUint64;
496 if (This->type_ == kInt64) {
497 *v =
static_cast<T
>(This->via_.i64);
500 *v =
static_cast<T
>(This->via_.u64);
506 static void Assign(
MpObject* This, T x) NLIB_NOEXCEPT { This->
Box(x); }
507 static void Construct(
MpObject* This, T x) NLIB_NOEXCEPT {
508 This->type_ = kUint64;
513 template <
class TR1_WORKAROUND>
514 struct MpObject::MyBox<float, FalseType, TR1_WORKAROUND> {
516 This->ReleaseIfNeeded();
517 This->type_ = kFloat;
523 switch (This->type_) {
528 *v =
static_cast<float>(This->via_.f64);
536 static void Assign(
MpObject* This,
float x) NLIB_NOEXCEPT { This->
Box(x); }
537 static void Construct(
MpObject* This,
float x) NLIB_NOEXCEPT {
538 This->type_ = kFloat;
543 template <
class TR1_WORKAROUND>
544 struct MpObject::MyBox<double, FalseType, TR1_WORKAROUND> {
546 This->ReleaseIfNeeded();
547 This->type_ = kDouble;
553 switch (This->type_) {
566 static void Assign(
MpObject* This,
double x) NLIB_NOEXCEPT { This->
Box(x); }
567 static void Construct(
MpObject* This,
double x) NLIB_NOEXCEPT {
568 This->type_ = kDouble;
573 template <
class STDSTRING>
574 struct MpObject::MyBox<STDSTRING, FalseType, FalseType> {
576 uint32_t n =
static_cast<uint32_t
>(str.size());
581 reinterpret_cast<const void*>(&str[0]),
591 NLIB_CATCH(std::bad_alloc&) {
return ENOMEM; }
596 template <
class T,
class ALLOC>
597 struct MpObject::MyBox<std::vector<T, ALLOC>, FalseType, FalseType> {
599 uint32_t n =
static_cast<uint32_t
>(vec.size());
604 for (uint32_t i = 0; i < n; ++i) {
605 e = (*tmp.via_.ary)[i].
Box(vec[i]);
614 NLIB_TRY { vec->resize(This->size_); }
615 NLIB_CATCH(std::bad_alloc&) {
return ENOMEM; }
616 for (uint32_t i = 0; i < This->size_; ++i) {
624 template <
class T,
class ALLOC>
625 struct MpObject::MyBox<Nlist<T, ALLOC>, FalseType, FalseType> {
627 size_t n = vec.
size();
632 for (
size_t i = 0; i < n; ++it, ++i) {
633 e = (*tmp.via_.ary)[i].
Box(*it);
644 for (uint32_t i = 0; i < This->size_; ++i) {
653 template <
class T1,
class T2>
654 struct MpObject::MyBox<std::pair<T1, T2>, FalseType, FalseType> {
659 e = (*tmp.via_.ary)[0].
Box(p.first);
661 e = (*tmp.via_.ary)[1].
Box(p.second);
671 e = (*This->via_.ary)[0].
Unbox(&p->first);
673 e = (*This->via_.ary)[1].
Unbox(&p->second);
679 #if defined(NLIB_CXX11_STDLIB_TUPLE) && defined(NLIB_CXX11_VARIADIC_TEMPLATES) 680 template <
class ...Args>
681 struct MpObject::MyBox<std::tuple<Args...>, FalseType, FalseType > {
683 template<
size_t N,
class HEAD>
685 return (*tmp->via_.ary)[N].Box(head);
687 template<
size_t N,
class HEAD,
class ...TAIL>
688 static errno_t BoxHelper(
MpObject* tmp,
const HEAD& head, TAIL&... tail) {
689 ErrnoT e = (*tmp->via_.ary)[N].
Box(head);
691 return BoxHelper<N + 1, TAIL...>(tmp, tail...);
693 template<
size_t N,
class HEAD>
695 return (*This->via_.ary)[N].Unbox(&head);
697 template<
size_t N,
class HEAD,
class ...TAIL>
698 static errno_t UnboxHelper(
const MpObject* This, HEAD& head, TAIL&... tail) {
701 return UnboxHelper<N + 1, TAIL...>(This, tail...);
703 template<
int ...>
struct seq {};
704 template<
int N,
int ...S>
struct gens : gens<N - 1, N - 1, S...> {};
706 struct gens<0, S...> {
707 typedef seq<S...> type;
711 return BoxHelper<0>(tmp, std::get<S>(p)...);
715 return UnboxHelper<0>(This, std::get<S>(p)...);
720 size_t count = std::tuple_size<std::tuple<Args...> >::value;
724 typedef typename gens<
sizeof...(Args)>::type MySeq;
725 e =
Box(&tmp, MySeq(), p);
733 if (
NLIB_UNLIKELY(This->size_ != std::tuple_size<std::tuple<Args...> >::value))
735 typedef typename gens<
sizeof...(Args)>::type MySeq;
736 return Unbox(This, MySeq(), *p);
741 template <
class K,
class V,
class Pr,
class Alloc>
742 struct MpObject::MyBox<std::map<K, V, Pr, Alloc>, FalseType, FalseType> {
744 typedef typename std::map<K, V, Pr, Alloc> maptype;
745 uint32_t n =
static_cast<uint32_t
>(m.size());
750 typename maptype::const_iterator it;
751 typename maptype::const_iterator it_end = m.end();
753 for (i = 0, it = m.begin(); it != it_end; ++it, ++i) {
767 for (uint32_t i = 0; i < This->size_; ++i) {
776 NLIB_TRY { (*m)[NLIB_MOVE(key)] = NLIB_MOVE(value); }
783 #ifdef NLIB_CXX11_STDLIB_UNORDERED 784 template <
class K,
class V,
class Hash,
class Pr,
class Alloc>
785 struct MpObject::MyBox<std::unordered_map<K, V, Hash, Pr, Alloc>, FalseType, FalseType > {
786 static errno_t Box(
MpObject* This,
const std::unordered_map<K, V, Hash, Pr, Alloc>& m) {
787 typedef typename std::unordered_map<K, V, Hash, Pr, Alloc> maptype;
788 uint32_t n =
static_cast<uint32_t
>(m.size());
793 typename maptype::const_iterator it;
794 typename maptype::const_iterator it_end = m.end();
796 for (i = 0, it = m.begin(); it != it_end; ++it, ++i) {
810 for (uint32_t i = 0; i < This->size_; ++i) {
819 NLIB_TRY { (*m)[NLIB_MOVE(key)] = NLIB_MOVE(value); }
829 return lhs.first == rhs.first && lhs.second == rhs.second;
832 return !(lhs == rhs);
835 return !(lhs == rhs);
838 template <u
int32_t n>
841 ErrnoT e = this->InitString(nn);
843 nlib_memcpy(this->GetString(), nn, reinterpret_cast<const void*>(&str[0]), nn);
847 template <
class T, u
int32_t n>
852 for (uint32_t i = 0; i < n; ++i) {
853 e = (*tmp.via_.ary)[i].
Box(vec[i]);
860 #ifdef NLIB_CXX11_STDLIB_ARRAY 861 template <
class T,
size_t n>
866 for (uint32_t i = 0; i < n; ++i) {
867 e = (*tmp.via_.ary)[i].
Box(vec[i]);
877 NLIB_EINVAL_IFNULL(a);
881 for (uint32_t i = 0; i < size_; ++i) {
891 NLIB_DEFINE_STD_SWAP(::nlib_ns::msgpack::MpObject)
892 NLIB_DEFINE_STD_SWAP(::nlib_ns::msgpack::MpObjectKv)
894 #if defined(_MSC_VER) && defined(nx_msgpack_EXPORTS) 895 #undef NLIB_VIS_PUBLIC 896 #define NLIB_VIS_PUBLIC NLIB_WINIMPORT 899 #endif // INCLUDE_NN_NLIB_MSGPACK_MPOBJECT_H_ nlib_utf8_t * GetString() noexcept
オブジェクトから文字列を取得します。
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 で指定されたクラスのコピーコンストラクタと代入演算子を禁止します。
非負整数型を表します。内部表現はuint64_tです。
MpObject() noexcept
デフォルトコンストラクタです。nil型に設定されます。
~MpObject() noexcept
デストラクタです。
const void * GetExt(int8_t *tp, uint32_t *n) const noexcept
オブジェクトから拡張データ型を取得します。
配列を表します。内部ではMpObjectの列として表現されています。
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 nlib_utf8_t * GetString() const noexcept
オブジェクトから文字列を取得します。
MpObject * SwapMapItem(const nlib_utf8_t *key, MpObject *obj) noexcept
obj の内容と連想配列内のオブジェクトの内容を交換します。
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
格納されている値が拡張データであるかどうかを調べます。
errno_t InitArray(uint32_t n) noexcept
オブジェクトをn 個の要素を持つ配列として初期化します。
void clear() noexcept
コンテナをクリアします。
浮動小数型を表します。内部表現はdoubleです。
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のデバッガ上での表示を改善します。
errno_t Box(const nlib_utf8_t *str) noexcept
文字列をボックス化します。
#define NLIB_TRY
例外が有効なときはtry, そうでなければif (true)が定義されます。
ObjectType GetType() const noexcept
オブジェクトの型を返します。
bool IsArray() const noexcept
格納されている値が配列であるかどうかを調べます。
MpObject(const T &x)
T型のオブジェクトをボックス化するコンストラクタです。
#define NLIB_NOEXCEPT
環境に合わせてnoexcept 又は同等の定義がされます。
errno_t InitString(const nlib_utf8_t *str) noexcept
オブジェクトを文字列として初期化します。
errno_t Unbox(nlib_utf8_t(&str)[n]) const noexcept
Unbox(T (&a)[n]) を御覧ください。
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に似た、コピーコンストラクタを持たないオブジェクトを格納可能なコンテナ類似クラスです。 ...
errno_t RemoveMapItem(const STDSTRING &str, MpObjectKv *kv) noexcept
キーを指定して連想配列内のキーとオブジェクトを削除します。
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
文字列を指定して連想配列内のオブジェクトを取得します。
errno_t InitMap(uint32_t n) noexcept
オブジェクトをn個の要素を持つ連想配列として初期化します。
MpObject * GetArrayItem(size_t n) noexcept
インデックスを指定して配列内のオブジェクトを取得します。
bool IsDouble() const noexcept
格納されている値が倍精度浮動小数点型であるかどうかを調べます。
MpObject型のキーと値のペアです。連想配列を格納するために利用されます。
errno_t GetMapItem(const nlib_utf8_t *str, size_t n, MpObjectKv **obj) noexcept
キーとなる非ヌル終端の文字列を指定して連想配列のキーと値のペアを取得します。
MessagePackのnil, 及びJSONのnullに対応するクラスです。
void swap(MpObjectKv &rhs) noexcept
オブジェクトの中身をスワップします。
bool IsInteger() const noexcept
格納されている値が整数値であるかどうかを調べます。
bool IsBinary() const noexcept
格納されている値がバイナリであるかどうかを調べます。
連想配列を表します。内部ではMpObjectのペアの列として表現されています。
errno_t Unbox(T(&a)[n]) const
オブジェクトの値をアンボックス化します。
errno_t Box(MpObject *obj, const T &v)
この関数テンプレートを特殊化してユーザー型のボックス化を定義することが可能です。