30 #define FOLLY_DYNAMIC_DEF_TYPEINFO(T) \ 31 constexpr const char* dynamic::TypeInfo<T>::name; \ 32 constexpr dynamic::Type dynamic::TypeInfo<T>::type; \ 43 #undef FOLLY_DYNAMIC_DEF_TYPEINFO 51 "TypeError: expected dynamic type `{}', but had type `{}'",
60 "TypeError: expected dynamic types `{}, but had types `{}' and `{}'",
77 #define FB_DYNAMIC_APPLY(type, apply) \ 81 apply(std::nullptr_t); \ 109 throw_exception<TypeError>(
"object",
type_);
115 #define FB_X(T) return CompareOp<T>::comp(*getAddress<T>(), *o.getAddress<T>()) 123 auto& integ = isInt() ? *
this : o;
124 auto& doubl = isInt() ? o : *
this;
125 return integ.
asInt() == doubl.asDouble();
130 #define FB_X(T) return *getAddress<T>() == *o.getAddress<T>(); 138 #define FB_X(T) *getAddress<T>() = *o.getAddress<T>() 143 #define FB_X(T) new (getAddress<T>()) T(*o.getAddress<T>()) 154 if (
type_ == o.type_) {
155 #define FB_X(T) *getAddress<T>() = std::move(*o.getAddress<T>()) 160 #define FB_X(T) new (getAddress<T>()) T(std::move(*o.getAddress<T>())) 170 if (
auto* parray = get_nothrow<Array>()) {
172 throw_exception<TypeError>(
"int64", idx.type());
174 if (idx < 0 || idx >= parray->size()) {
175 throw_exception<std::out_of_range>(
"out of range in dynamic array");
177 return (*parray)[size_t(idx.asInt())];
178 }
else if (
auto* pobject = get_nothrow<ObjectImpl>()) {
179 auto it = pobject->
find(idx);
180 if (it == pobject->end()) {
181 throw_exception<std::out_of_range>(
182 sformat(
"couldn't find key {} in dynamic object", idx.asString()));
186 throw_exception<TypeError>(
"object/array",
type());
191 auto* pobject = get_nothrow<ObjectImpl>();
193 throw_exception<TypeError>(
"object",
type());
195 auto it = pobject->find(idx);
196 if (it == pobject->end()) {
197 throw_exception<std::out_of_range>(
198 sformat(
"couldn't find key {} in dynamic object", idx));
204 auto& obj = get<ObjectImpl>();
205 auto ret = obj.emplace(k,
nullptr);
206 return ret.first->second;
210 auto& obj = get<ObjectImpl>();
211 auto it = obj.find(k);
212 return it == obj.end() ?
v : it->second;
216 auto& obj = get<ObjectImpl>();
217 auto it = obj.find(k);
219 if (it == obj.end()) {
227 auto& obj = get<ObjectImpl>();
228 auto it = obj.find(k);
230 if (it == obj.end()) {
238 auto& obj = get<ObjectImpl>();
239 auto it = obj.find(k);
240 return std::move(it == obj.end() ?
v : it->second);
244 if (
auto* parray = get_nothrow<Array>()) {
246 throw_exception<TypeError>(
"int64", idx.type());
248 if (idx < 0 || idx >= parray->size()) {
251 return &(*parray)[size_t(idx.asInt())];
252 }
else if (
auto* pobject = get_nothrow<ObjectImpl>()) {
253 auto it = pobject->
find(idx);
254 if (it == pobject->end()) {
259 throw_exception<TypeError>(
"object/array",
type());
264 auto* pobject = get_nothrow<ObjectImpl>();
266 throw_exception<TypeError>(
"object",
type());
268 auto it = pobject->
find(idx);
269 if (it == pobject->end()) {
276 if (
auto* ar = get_nothrow<Array>()) {
279 if (
auto* obj = get_nothrow<ObjectImpl>()) {
282 if (
auto* str = get_nothrow<std::string>()) {
285 throw_exception<TypeError>(
"array/object/string",
type());
289 auto& arr = get<Array>();
290 return get<Array>().erase(
291 arr.begin() + (first - arr.begin()), arr.begin() + (last - arr.begin()));
302 auto h = std::hash<std::pair<dynamic, dynamic>>{};
307 [&](
auto acc,
auto item) {
return acc +
h(item); });
312 return std::hash<int64_t>()(getInt());
314 return std::hash<double>()(getDouble());
316 return std::hash<bool>()(getBool());
319 return Hash()(getString());
325 #define FB_X(T) return TypeInfo<T>::name 332 if (
type_ == NULLT) {
336 #define FB_X(T) detail::Destroy::destroy(getAddress<T>()) 351 for (
const auto&
pair : target.
items()) {
353 if (it == source.
items().end()) {
356 diff[
pair.first] = merge_diff(source[
pair.first], target[
pair.first]);
361 for (
const auto&
pair : source.
items()) {
363 if (it == target.
items().end()) {
364 diff[
pair.first] =
nullptr;
372 auto const&
tokens = jsonPtr.tokens();
377 for (
auto const& token :
tokens) {
387 throw_exception<TypeError>(
"object", dyn->
type());
390 if (token.size() > 1 && token.at(0) ==
'0') {
391 throw std::invalid_argument(
392 "Leading zero not allowed when indexing arrays");
395 if (token.size() == 1 && token.at(0) ==
'-') {
399 auto const idx = folly::to<size_t>(token);
400 dyn = idx < parray->
size() ? &(*parray)[idx] :
nullptr;
404 auto const it = pobject->find(token);
405 dyn = it != pobject->
end() ? &it->second :
nullptr;
408 throw_exception<TypeError>(
"object/array", dyn->
type());
bool operator<(dynamic const &o) const
std::vector< dynamic > Array
IfIsNonStringDynamicConvertible< K, dynamic > getDefault(K &&k, const dynamic &v=dynamic::object) const &
#define FB_DYNAMIC_APPLY(type, apply)
const char * typeName() const
void accumulate(std::vector< std::size_t > &a, std::vector< std::size_t > const &d)
dynamic const & atImpl(dynamic const &) const &
std::string sformat(StringPiece fmt, Args &&...args)
constexpr detail::Map< Move > move
auto begin(TestAdlIterable &instance)
TypeError & operator=(const TypeError &) noexcept(std::is_nothrow_copy_assignable< std::runtime_error >::value)
—— Concurrent Priority Queue Implementation ——
requires E e noexcept(noexcept(s.error(std::move(e))))
IfIsNonStringDynamicConvertible< K, dynamic & > operator[](K &&)&
TypeError(const std::string &expected, dynamic::Type actual)
uint64_t hash_range(Iter begin, Iter end, uint64_t hash=0, Hash hasher=Hash())
const dynamic * get_ptrImpl(dynamic const &) const &
static dynamic merge_diff(const dynamic &source, const dynamic &target)
FOLLY_ALWAYS_INLINE void assume_unreachable()
#define FOLLY_DYNAMIC_DEF_TYPEINFO(T)
bool operator==(dynamic const &o) const
dynamic & operator=(dynamic const &)
auto end(TestAdlIterable &instance)
IfIsNonStringDynamicConvertible< K, const_item_iterator > find(K &&) const
static const char *const value
IfIsNonStringDynamicConvertible< K, std::size_t > erase(K &&)
uint64_t diff(uint64_t a, uint64_t b)
IterableProxy< const_item_iterator > items() const
IfIsNonStringDynamicConvertible< K, dynamic const & > at(K &&) const &
Array::const_iterator const_iterator
T * get_nothrow()&noexcept
static const char tokens[256]
const_iterator end() const
const dynamic * get_ptr(json_pointer const &) const &
constexpr detail::First first