common/util/cpp/HsStruct.cpp (217 lines of code) (raw):

// Copyright (c) Facebook, Inc. and its affiliates. #include "cpp/HsStruct.h" #include "cpp/Marshallable.h" /* * HsJSON */ HsJSON::HsJSON(const folly::dynamic& value) { switch (value.type()) { case folly::dynamic::NULLT: type = Type::Null; break; case folly::dynamic::BOOL: type = Type::Bool; integral = value.asBool(); break; case folly::dynamic::INT64: type = Type::Integral; integral = value.asInt(); break; case folly::dynamic::DOUBLE: type = Type::Real; real = value.asDouble(); break; case folly::dynamic::STRING: type = Type::String; new (&string) HsString(value.asString()); break; case folly::dynamic::ARRAY: type = Type::Array; { std::vector<HsJSON> v; v.reserve(value.size()); for (const folly::dynamic& i : value) { v.emplace_back(i); } new (&array) HsArray<HsJSON>(std::move(v)); } break; case folly::dynamic::OBJECT: type = Type::Object; { std::vector<HsString> keys; std::vector<HsJSON> values; keys.reserve(value.size()); values.reserve(value.size()); for (const auto& i : value.items()) { keys.emplace_back(i.first.asString()); values.emplace_back(i.second); } new (&object) HsObject<HsJSON>(std::move(keys), std::move(values)); } break; } } folly::dynamic HsJSON::toDynamic() && { switch (type) { case Type::Null: return folly::dynamic(); case Type::Bool: return folly::dynamic(static_cast<bool>(integral)); case Type::Integral: return folly::dynamic(integral); case Type::Real: return folly::dynamic(real); case Type::String: return folly::dynamic(std::move(string).toStdString()); case Type::Array: { auto res = folly::dynamic::array(); auto end = std::make_move_iterator(array.end()); for (auto itr = std::make_move_iterator(array.begin()); itr != end; itr++) { res.push_back(std::move(*itr).toDynamic()); } return res; } case Type::Object: { folly::dynamic res = folly::dynamic::object; auto items = std::move(object).take_items(); // Manual version of zipping 2 iterators together auto key_itr = std::make_move_iterator(items.first.begin()); auto key_end = std::make_move_iterator(items.first.end()); auto val_itr = std::make_move_iterator(items.second.begin()); auto val_end = std::make_move_iterator(items.second.end()); while (key_itr != key_end && val_itr != val_end) { res.insert( std::move(*key_itr).toStdString(), std::move(*val_itr).toDynamic()); key_itr++; val_itr++; } return res; } } folly::assume_unreachable(); } void HsJSON::construct(HsJSON&& other) { DCHECK(this != &other); type = other.type; switch (type) { case Type::Null: break; case Type::Bool: case Type::Integral: integral = other.integral; break; case Type::Real: real = other.real; break; case Type::String: new (&string) HsString(std::move(other.string)); break; case Type::Array: new (&array) HsArray<HsJSON>(std::move(other.array)); break; case Type::Object: new (&object) HsObject<HsJSON>(std::move(other.object)); break; } } void HsJSON::destruct() { if (type == Type::String) { string.~HsString(); } else if (type == Type::Array) { array.~HsArray(); } else if (type == Type::Object) { object.~HsMap(); } } void ctorHsJSONNull(HsJSON* p) noexcept { new (p) HsJSON(); } void ctorHsJSONBool(HsJSON* p, bool b) noexcept { new (p) HsJSON(b); } void ctorHsJSONInt(HsJSON* p, int64_t i) noexcept { new (p) HsJSON(i); } void ctorHsJSONDouble(HsJSON* p, double d) noexcept { new (p) HsJSON(d); } void ctorHsJSONString(HsJSON* p, HsString* txt) noexcept { new (p) HsJSON(std::move(*txt)); } void ctorHsJSONArray(HsJSON* p, HsArray<HsJSON>* a) noexcept { new (p) HsJSON(std::move(*a)); } void ctorHsJSONObject(HsJSON* p, HsObject<HsJSON>* o) noexcept { new (p) HsJSON(std::move(*o)); } /* * HsObject */ extern "C" void common_hs_ctorHsObjectJSON( HsObject<HsJSON>* p, HsArray<HsString>* keys, HsArray<HsJSON>* vals) { new (p) HsObject<HsJSON>( std::move(*keys).toStdVector(), std::move(*vals).toStdVector()); } /* * HsStringPiece */ HsStringPiece* newHsStringPiece(const char* p, size_t n) noexcept { return new HsStringPiece(p, n); } void ctorHsStringPiece(HsRange<char>* ret, const char* p, size_t n) noexcept { new (ret) HsStringPiece(p, n); } /* * HsString */ HsString* newHsString(const char* p, size_t n) noexcept { return new HsString(std::string(p, n)); } void ctorHsString(HsString* ret, const char* p, size_t n) noexcept { new (ret) HsString(std::string(p, n)); } /* * HsEither */ // HsEither<char,char> instead of HsEither<void,void> just to keep class // definition happy. void* newHsEither(HsEitherTag tag, void* val) { return new DummyHsEither(tag, val); } HS_DEFINE_MARSHALLABLE(HsMaybeInt, HsMaybe<int64_t>); HS_DEFINE_MARSHALLABLE(HsMaybeDouble, HsMaybe<double>); HS_DEFINE_MARSHALLABLE(HsMaybeString, HsMaybe<HsString>); HS_DEFINE_MARSHALLABLE(HsEitherStringInt, HsEither<HsString, int64_t>); HS_DEFINE_MARSHALLABLE(HsEitherStringDouble, HsEither<HsString, double>); HS_DEFINE_MARSHALLABLE(HsEitherStringString, HsEither<HsString, HsString>); HS_DEFINE_MARSHALLABLE( HsEitherStringArrayInt, HsEither<HsString, HsArray<int64_t>>); HS_DEFINE_MARSHALLABLE( HsEitherStringArrayDouble, HsEither<HsString, HsArray<double>>); HS_DEFINE_MARSHALLABLE( HsEitherStringArrayString, HsEither<HsString, HsArray<HsString>>); HS_DEFINE_MARSHALLABLE(HsString, HsString); HS_DEFINE_MARSHALLABLE(HsStringPiece, HsStringPiece); HS_DEFINE_MARSHALLABLE(HsArrayInt32, HsArray<int32_t>); HS_DEFINE_MARSHALLABLE(HsArrayInt64, HsArray<int64_t>); HS_DEFINE_MARSHALLABLE(HsArrayUInt32, HsArray<uint32_t>); HS_DEFINE_MARSHALLABLE(HsArrayUInt64, HsArray<uint64_t>); HS_DEFINE_MARSHALLABLE(HsArrayFloat, HsArray<float>); HS_DEFINE_MARSHALLABLE(HsArrayDouble, HsArray<double>); HS_DEFINE_MARSHALLABLE(HsArrayString, HsArray<HsString>); HS_DEFINE_MARSHALLABLE(HsArrayJSON, HsArray<HsJSON>); HS_DEFINE_MARSHALLABLE(HsMapIntInt, HsMap<int64_t, int64_t>); HS_DEFINE_MARSHALLABLE(HsMapIntDouble, HsMap<int64_t, double>); HS_DEFINE_MARSHALLABLE(HsMapIntString, HsMap<int64_t, HsString>); HS_DEFINE_MARSHALLABLE(HsMapStringInt, HsMap<HsString, int64_t>); HS_DEFINE_MARSHALLABLE(HsMapStringDouble, HsMap<HsString, double>); HS_DEFINE_MARSHALLABLE(HsMapStringString, HsMap<HsString, HsString>); HS_DEFINE_MARSHALLABLE(HsObjectJSON, HsObject<HsJSON>); HS_DEFINE_MARSHALLABLE(HsJSON, HsJSON); HS_OPTION_CPP(Bool, bool); HS_OPTION_CPP(Int32, int32_t); HS_OPTION_CPP(Int64, int64_t); HS_OPTION_CPP(UInt32, uint32_t); HS_OPTION_CPP(UInt64, uint64_t); HS_OPTION_CPP(Float, float); HS_OPTION_CPP(Double, double); HS_OPTION_CPP(String, HsString); HS_OPTION_CPP(StringView, HsStringPiece); HS_OPTION_CPP(HsJSON, HsJSON); // No bool as std::vector<bool> doesn't define Container HS_DEFINE_ARRAY_CONSTRUCTIBLE(Int32, int32_t); HS_DEFINE_ARRAY_CONSTRUCTIBLE(Int64, int64_t); HS_DEFINE_ARRAY_CONSTRUCTIBLE(UInt32, uint32_t); HS_DEFINE_ARRAY_CONSTRUCTIBLE(UInt64, uint64_t); HS_DEFINE_ARRAY_CONSTRUCTIBLE(Float, float); HS_DEFINE_ARRAY_CONSTRUCTIBLE(Double, double); HS_DEFINE_ARRAY_CONSTRUCTIBLE(String, HsString); HS_DEFINE_ARRAY_CONSTRUCTIBLE(StringView, HsStringPiece); HS_DEFINE_ARRAY_CONSTRUCTIBLE(HsJSON, HsJSON);