enables string_view
This commit is contained in:
parent
b76eaabd9b
commit
7d61c429f6
@ -212,7 +212,7 @@ class json_sax_dom_parser
|
||||
bool key(string_t& val)
|
||||
{
|
||||
// add null at given key and store the reference for later
|
||||
object_element = &(ref_stack.back()->m_value.object->operator[](to_map_key<typename object_t::key_type>(val)));
|
||||
object_element = &(ref_stack.back()->m_value.object->operator[](BasicJsonType::to_map_key_(val)));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -406,7 +406,7 @@ class json_sax_dom_callback_parser
|
||||
// add discarded value at given key and store the reference for later
|
||||
if (keep and ref_stack.back())
|
||||
{
|
||||
object_element = &(ref_stack.back()->m_value.object->operator[](to_map_key<typename object_t::key_type>(val)) = discarded);
|
||||
object_element = &(ref_stack.back()->m_value.object->operator[](BasicJsonType::to_map_key_(val)) = discarded);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@ -67,6 +67,7 @@ template<typename IteratorType> class iteration_proxy
|
||||
}
|
||||
|
||||
/// return key of the iterator
|
||||
// this code is strange, why are returning a std::string & instead of just a std::string
|
||||
const std::string& key() const
|
||||
{
|
||||
assert(anchor.m_object != nullptr);
|
||||
@ -86,7 +87,8 @@ template<typename IteratorType> class iteration_proxy
|
||||
|
||||
// use key from the object
|
||||
case value_t::object:
|
||||
return anchor.key();
|
||||
array_index_str = anchor.key();
|
||||
return array_index_str;
|
||||
|
||||
// use an empty key for all primitive types
|
||||
default:
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
//
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
#include <functional>
|
||||
|
||||
#ifdef USE_EXPERIMENTAL_STRINGVIEW
|
||||
#include <experimental/string_view>
|
||||
@ -42,12 +43,29 @@ struct json_string_view
|
||||
json_string_view(const char *data, size_t size) :
|
||||
data_(data), size_(size)
|
||||
{}
|
||||
|
||||
json_string_view(const char *data) :
|
||||
data_(data), size_(strlen(data))
|
||||
{}
|
||||
|
||||
json_string_view(const std::string &s) :
|
||||
data_(s.c_str()), size_(s.size())
|
||||
{
|
||||
}
|
||||
|
||||
json_string_view (const json_string_view &rhs) :
|
||||
data_(rhs.data_), size_(rhs.size_)
|
||||
{}
|
||||
|
||||
json_string_view (json_string_view &&rhs) :
|
||||
data_(rhs.data_), size_(rhs.size_)
|
||||
{}
|
||||
|
||||
const char *data() const
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return size_;
|
||||
@ -93,12 +111,50 @@ bool operator <(const json_string_view &l, const json_string_view &r)
|
||||
return ls < rs;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream &operator <<(std::ostream &l, const json_string_view &r)
|
||||
{
|
||||
return l << std::string(r);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// this is gross, yes I know, it probably shouldn't be done this way, copied from example
|
||||
// on the internetz
|
||||
namespace std {
|
||||
|
||||
template <>
|
||||
struct hash<nlohmann::json_string_view>
|
||||
{
|
||||
hash<std::string> hasher;
|
||||
|
||||
size_t operator()(const nlohmann::json_string_view& k_) const
|
||||
{
|
||||
std::string k(k_.data(), k_.size());
|
||||
// Compute individual hash values for two data members and combine them using XOR and bit shifting
|
||||
return hasher(k);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
namespace nlohmann {
|
||||
|
||||
// -----------------------
|
||||
|
||||
|
||||
struct json_const_char_star {
|
||||
const char *data;
|
||||
|
||||
json_const_char_star(const char *s);
|
||||
json_const_char_star(const std::string &s);
|
||||
json_const_char_star(const json_const_char_star &rhs) :
|
||||
data(rhs.data) {}
|
||||
json_const_char_star(json_const_char_star &&rhs) :
|
||||
data(rhs.data) {}
|
||||
} ;
|
||||
|
||||
inline
|
||||
@ -120,6 +176,35 @@ bool operator <(const json_const_char_star &l, const json_const_char_star &r)
|
||||
return l.data < r.data;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream &operator <<(std::ostream &l, const json_const_char_star &r)
|
||||
{
|
||||
return l << std::string(r.data);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// this is gross, yes I know, it probably shouldn't be done this way, copied from example
|
||||
// on the internetz
|
||||
namespace std {
|
||||
|
||||
template <>
|
||||
struct hash<nlohmann::json_const_char_star>
|
||||
{
|
||||
hash<unsigned long long> hasher;
|
||||
|
||||
size_t operator()(const nlohmann::json_const_char_star& k) const
|
||||
{
|
||||
// Compute individual hash values for two data members and combine them using XOR and bit shifting
|
||||
return hasher(reinterpret_cast<unsigned long long>(k.data));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
namespace nlohmann {
|
||||
|
||||
// -------------------
|
||||
|
||||
// why am I having trouble getting rid of this? it must be too late
|
||||
@ -135,10 +220,28 @@ template<typename R> inline R to_lookup_key(const json_string_view &s);
|
||||
template<typename R> inline R to_lookup_key(const std::string &s);
|
||||
template<typename R> inline R to_lookup_key(const json_const_char_star &s);
|
||||
|
||||
template<typename T, typename R=std::string>
|
||||
inline R to_concatable_string(const T &t)
|
||||
template<typename R, typename T> R to_concatable_string(const T &t);
|
||||
|
||||
|
||||
template<>
|
||||
inline
|
||||
std::string to_map_key(const std::string &t)
|
||||
{
|
||||
return R(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline
|
||||
std::string to_lookup_key(const std::string &t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline
|
||||
std::string to_concatable_string(const std::string &t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
// -------------------
|
||||
@ -196,11 +299,17 @@ inline json_string_view to_lookup_key(const __stupid_const_char_typedef &s)
|
||||
return json_string_view(s, strlen(s));
|
||||
} ;
|
||||
|
||||
template<>
|
||||
inline
|
||||
std::string to_concatable_string(const json_string_view &t)
|
||||
{
|
||||
return std::string(t.data(), t.size());
|
||||
}
|
||||
|
||||
// -----------------------
|
||||
|
||||
|
||||
template<>
|
||||
inline json_const_char_star to_map_key(const std::string &s)
|
||||
inline const char *generate_json_const_char_star(const std::string &s)
|
||||
{
|
||||
static std::set<std::string> strings;
|
||||
|
||||
@ -213,9 +322,15 @@ inline json_const_char_star to_map_key(const std::string &s)
|
||||
i = strings.find(str);
|
||||
}
|
||||
|
||||
return { i->c_str() };
|
||||
return i->c_str();
|
||||
} ;
|
||||
|
||||
template<>
|
||||
inline json_const_char_star to_map_key(const std::string &s)
|
||||
{
|
||||
return json_const_char_star(s);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline json_const_char_star to_map_key(const __stupid_const_char_typedef &s)
|
||||
{
|
||||
@ -253,5 +368,16 @@ std::string to_concatable_string(const json_const_char_star &t)
|
||||
return std::string(t.data);
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
inline json_const_char_star::json_const_char_star(const std::string &s) :
|
||||
data(generate_json_const_char_star(s))
|
||||
{
|
||||
}
|
||||
|
||||
inline json_const_char_star::json_const_char_star(const char *s) :
|
||||
data(generate_json_const_char_star(s))
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -659,9 +659,10 @@ class binary_writer
|
||||
for (const auto& el : *j.m_value.object)
|
||||
{
|
||||
write_number_with_ubjson_prefix(el.first.size(), true);
|
||||
auto writable = BasicJsonType::to_concatable_string_(el.first);
|
||||
oa->write_characters(
|
||||
reinterpret_cast<const CharType*>(el.first.c_str()),
|
||||
el.first.size());
|
||||
reinterpret_cast<const CharType*>(writable.c_str()),
|
||||
writable.size());
|
||||
write_ubjson(el.second, use_count, use_type, prefix_required);
|
||||
}
|
||||
|
||||
|
||||
@ -106,7 +106,7 @@ class serializer
|
||||
{
|
||||
o->write_characters(indent_string.c_str(), new_indent);
|
||||
o->write_character('\"');
|
||||
dump_escaped(to_concatable_string(i->first), ensure_ascii);
|
||||
dump_escaped(BasicJsonType::to_concatable_string_(i->first), ensure_ascii);
|
||||
o->write_characters("\": ", 3);
|
||||
dump(i->second, true, ensure_ascii, indent_step, new_indent);
|
||||
o->write_characters(",\n", 2);
|
||||
@ -117,7 +117,7 @@ class serializer
|
||||
assert(std::next(i) == val.m_value.object->cend());
|
||||
o->write_characters(indent_string.c_str(), new_indent);
|
||||
o->write_character('\"');
|
||||
dump_escaped(to_concatable_string(i->first), ensure_ascii);
|
||||
dump_escaped(BasicJsonType::to_concatable_string_(i->first), ensure_ascii);
|
||||
o->write_characters("\": ", 3);
|
||||
dump(i->second, true, ensure_ascii, indent_step, new_indent);
|
||||
|
||||
@ -134,7 +134,7 @@ class serializer
|
||||
for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
|
||||
{
|
||||
o->write_character('\"');
|
||||
dump_escaped(to_concatable_string(i->first), ensure_ascii);
|
||||
dump_escaped(BasicJsonType::to_concatable_string_(i->first), ensure_ascii);
|
||||
o->write_characters("\":", 2);
|
||||
dump(i->second, false, ensure_ascii, indent_step, current_indent);
|
||||
o->write_character(',');
|
||||
@ -144,7 +144,7 @@ class serializer
|
||||
assert(i != val.m_value.object->cend());
|
||||
assert(std::next(i) == val.m_value.object->cend());
|
||||
o->write_character('\"');
|
||||
dump_escaped(to_concatable_string(i->first), ensure_ascii);
|
||||
dump_escaped(BasicJsonType::to_concatable_string_(i->first), ensure_ascii);
|
||||
o->write_characters("\":", 2);
|
||||
dump(i->second, false, ensure_ascii, indent_step, current_indent);
|
||||
|
||||
|
||||
@ -164,8 +164,26 @@ NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||
class basic_json
|
||||
{
|
||||
public:
|
||||
// these definitions should come
|
||||
typedef json_string_view map_key_type;
|
||||
// these definitions should come
|
||||
typedef json_string_view map_key_type;
|
||||
|
||||
template<typename T>
|
||||
static map_key_type to_map_key_(const T& t)
|
||||
{
|
||||
return to_map_key<map_key_type>(t);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static map_key_type to_lookup_key_(const T& t)
|
||||
{
|
||||
return to_lookup_key<map_key_type>(t);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static StringType to_concatable_string_(const T& t)
|
||||
{
|
||||
return to_concatable_string<StringType>(t);
|
||||
}
|
||||
|
||||
private:
|
||||
template<detail::value_t> friend struct detail::external_constructor;
|
||||
@ -390,7 +408,7 @@ class basic_json
|
||||
// on find() and count() calls prevents unnecessary string construction.
|
||||
using object_comparator_t = std::less<>;
|
||||
#else
|
||||
using object_comparator_t = std::less<StringType>;
|
||||
using object_comparator_t = std::less<map_key_type>;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@ -479,7 +497,7 @@ class basic_json
|
||||
using object_t = ObjectType<map_key_type,
|
||||
basic_json,
|
||||
object_comparator_t,
|
||||
AllocatorType<std::pair<const StringType,
|
||||
AllocatorType<std::pair<const map_key_type,
|
||||
basic_json>>>;
|
||||
|
||||
/*!
|
||||
@ -1441,7 +1459,7 @@ class basic_json
|
||||
{
|
||||
auto element = element_ref.moved_or_copied();
|
||||
m_value.object->emplace(
|
||||
std::move(to_map_key<typename object_t::key_type>(*((*element.m_value.array)[0].m_value.string))),
|
||||
std::move(to_map_key_(*((*element.m_value.array)[0].m_value.string))),
|
||||
std::move((*element.m_value.array)[1]));
|
||||
});
|
||||
}
|
||||
@ -2922,6 +2940,13 @@ class basic_json
|
||||
}
|
||||
}
|
||||
|
||||
// I'm not exactly sure why the compiler doesn't opt for the size_t when proposed x[0]
|
||||
// but for some reason it needs this bit of help
|
||||
reference at(int idx)
|
||||
{
|
||||
return at(static_cast<size_t>(idx));
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief access specified array element with bounds checking
|
||||
|
||||
@ -2969,6 +2994,13 @@ class basic_json
|
||||
}
|
||||
}
|
||||
|
||||
// I'm not exactly sure why the compiler doesn't opt for the size_t when proposed x[0]
|
||||
// but for some reason it needs this bit of help
|
||||
const_reference at(int idx) const
|
||||
{
|
||||
return at(static_cast<size_t>(idx));
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief access specified object element with bounds checking
|
||||
|
||||
@ -3011,7 +3043,7 @@ class basic_json
|
||||
JSON_CATCH (std::out_of_range&)
|
||||
{
|
||||
// create better exception explanation
|
||||
JSON_THROW(out_of_range::create(403, "key '" + to_concatable_string(key) + "' not found"));
|
||||
JSON_THROW(out_of_range::create(403, "key '" + to_concatable_string_(key) + "' not found"));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -3019,13 +3051,17 @@ class basic_json
|
||||
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
reference at(const T& key_)
|
||||
{
|
||||
auto key = to_lookup_key<typename object_t::key_type>(key_);
|
||||
return at(key);
|
||||
}
|
||||
|
||||
/*
|
||||
// this might be necessary later, not sure
|
||||
|
||||
template<typename T>
|
||||
reference at(const T& key_)
|
||||
{
|
||||
auto key = to_lookup_key(key_);
|
||||
return at(key);
|
||||
}
|
||||
*/
|
||||
|
||||
/*!
|
||||
@brief access specified object element with bounds checking
|
||||
@ -3057,7 +3093,7 @@ class basic_json
|
||||
`at()`. It also demonstrates the different exceptions that can be thrown.,
|
||||
at__object_t_key_type_const}
|
||||
*/
|
||||
const_reference at(const typename object_t::key_type & key) const
|
||||
const_reference at(const typename object_t::key_type& key) const
|
||||
{
|
||||
// at only works for objects
|
||||
if (JSON_LIKELY(is_object()))
|
||||
@ -3069,7 +3105,7 @@ class basic_json
|
||||
JSON_CATCH (std::out_of_range&)
|
||||
{
|
||||
// create better exception explanation
|
||||
JSON_THROW(out_of_range::create(403, "key '" + to_concatable_string(key) + "' not found"));
|
||||
JSON_THROW(out_of_range::create(403, "key '" + to_concatable_string_(key) + "' not found"));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -3078,12 +3114,16 @@ class basic_json
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const_reference at(const T& key_) const
|
||||
{
|
||||
auto key = to_lookup_key<typename object_t::key_type>(key_);
|
||||
return at(key);
|
||||
}
|
||||
/*
|
||||
// this might be necessary later, not sure
|
||||
|
||||
template<typename T>
|
||||
const_reference at(const T& key_) const
|
||||
{
|
||||
auto key = to_lookup_key(key_);
|
||||
return at(key);
|
||||
}
|
||||
*/
|
||||
|
||||
/*!
|
||||
@brief access specified array element
|
||||
@ -3136,12 +3176,14 @@ class basic_json
|
||||
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
|
||||
}
|
||||
|
||||
|
||||
// I'm not exactly sure why the compiler doesn't opt for the size_t when proposed x[0]
|
||||
// but for some reason it needs this bit of help
|
||||
reference operator[](int idx)
|
||||
{
|
||||
return operator[](size_t(idx));
|
||||
}
|
||||
|
||||
{
|
||||
return operator[](size_t(idx));
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
@brief access specified array element
|
||||
@ -3173,10 +3215,12 @@ class basic_json
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
|
||||
}
|
||||
|
||||
// I'm not exactly sure why the compiler doesn't opt for the size_t when proposed x[0]
|
||||
// but for some reason it needs this bit of help
|
||||
const_reference operator[](int idx) const
|
||||
{
|
||||
return operator[](size_t(idx));
|
||||
}
|
||||
{
|
||||
return operator[](size_t(idx));
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief access specified object element
|
||||
@ -3218,11 +3262,13 @@ class basic_json
|
||||
// operator[] only works for objects
|
||||
if (JSON_LIKELY(is_object()))
|
||||
{
|
||||
auto i = m_value.object->find(key_);
|
||||
if (i != m_value.object->end())
|
||||
return i->second;
|
||||
|
||||
auto key = to_map_key<typename object_t::key_type>(key_);
|
||||
auto i = m_value.object->find(key_);
|
||||
if (i != m_value.object->end())
|
||||
{
|
||||
return i->second;
|
||||
}
|
||||
|
||||
auto key = to_map_key_(key_);
|
||||
return m_value.object->operator[](key);
|
||||
}
|
||||
|
||||
@ -3298,24 +3344,25 @@ class basic_json
|
||||
|
||||
@since version 1.1.0
|
||||
*/
|
||||
template<typename T>
|
||||
reference operator[](const T &key_)
|
||||
template<typename T>
|
||||
reference operator[](const T& key_)
|
||||
{
|
||||
auto key = to_lookup_key<typename object_t::key_type>(key_);
|
||||
return operator[](key);
|
||||
auto key = to_lookup_key_(key_);
|
||||
return operator[](key);
|
||||
}
|
||||
|
||||
// reference operator[](const std::string &key_)
|
||||
// {
|
||||
// auto key = to_map_key<typename object_t::key_type>(key_);
|
||||
// return operator[](key);
|
||||
// }
|
||||
//
|
||||
// reference operator[](const char *key_)
|
||||
// {
|
||||
// auto key = to_map_key<typename object_t::key_type>(key_);
|
||||
// return operator[](key);
|
||||
// }
|
||||
// might be neccessary later
|
||||
// reference operator[](const std::string &key_)
|
||||
// {
|
||||
// auto key = to_lookup_key_(key_);
|
||||
// return operator[](key);
|
||||
// }
|
||||
//
|
||||
// reference operator[](const char *key_)
|
||||
// {
|
||||
// auto key = to_lookup_key_(key_);
|
||||
// return operator[](key);
|
||||
// }
|
||||
|
||||
/*!
|
||||
@brief read-only access specified object element
|
||||
@ -3347,24 +3394,25 @@ class basic_json
|
||||
|
||||
@since version 1.1.0
|
||||
*/
|
||||
template<typename T>
|
||||
const_reference operator[](const T &key_) const
|
||||
template<typename T>
|
||||
const_reference operator[](const T& key_) const
|
||||
{
|
||||
auto key = to_lookup_key<typename object_t::key_type>(key_);
|
||||
return operator[](key);
|
||||
auto key = to_lookup_key_(key_);
|
||||
return operator[](key);
|
||||
}
|
||||
|
||||
// const_reference operator[](const std::string &key_) const
|
||||
// {
|
||||
// auto key = to_map_key<typename object_t::key_type>(key_);
|
||||
// return operator[](key);
|
||||
// }
|
||||
//
|
||||
// const_reference operator[](const char *key_) const
|
||||
// {
|
||||
// auto key = to_map_key<typename object_t::key_type>(key_);
|
||||
// return operator[](key);
|
||||
// }
|
||||
// might be necessary later
|
||||
// const_reference operator[](const std::string &key_) const
|
||||
// {
|
||||
// auto key = to_lookup_key_(key_);
|
||||
// return operator[](key);
|
||||
// }
|
||||
//
|
||||
// const_reference operator[](const char *key_) const
|
||||
// {
|
||||
// auto key = to_lookup_key_(key_);
|
||||
// return operator[](key);
|
||||
// }
|
||||
|
||||
/*!
|
||||
@brief access specified object element with default value
|
||||
@ -3842,7 +3890,7 @@ class basic_json
|
||||
|
||||
@since version 1.0.0
|
||||
*/
|
||||
size_type erase(const typename object_t::key_type & key)
|
||||
size_type erase(const typename object_t::key_type& key)
|
||||
{
|
||||
// this erase only works for objects
|
||||
if (JSON_LIKELY(is_object()))
|
||||
@ -3853,24 +3901,27 @@ class basic_json
|
||||
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
size_type erase(const T& key_)
|
||||
{
|
||||
auto key = to_map_key<typename object_t::key_type>(key_);
|
||||
return erase(key);
|
||||
}
|
||||
|
||||
void erase(const iterator &key)
|
||||
{
|
||||
// this erase only works for objects
|
||||
if (JSON_LIKELY(is_object()))
|
||||
/*
|
||||
template<typename T>
|
||||
size_type erase(const T& key_)
|
||||
{
|
||||
m_value.object->erase(key.m_it.object_iterator);
|
||||
auto key = to_lookup_key(key_);
|
||||
return erase(key);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
void erase(const iterator& key)
|
||||
{
|
||||
// this erase only works for objects
|
||||
if (JSON_LIKELY(is_object()))
|
||||
{
|
||||
m_value.object->erase(key.m_it.object_iterator);
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
|
||||
}
|
||||
*/
|
||||
|
||||
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief remove element from a JSON array given an index
|
||||
|
||||
@ -3915,8 +3966,8 @@ class basic_json
|
||||
|
||||
void erase(int idx)
|
||||
{
|
||||
erase(static_cast<size_t>(idx));
|
||||
}
|
||||
erase(static_cast<size_t>(idx));
|
||||
}
|
||||
/// @}
|
||||
|
||||
|
||||
@ -3956,7 +4007,7 @@ class basic_json
|
||||
|
||||
if (is_object())
|
||||
{
|
||||
result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
|
||||
result.m_it.object_iterator = m_value.object->find(std::forward<map_key_type>(to_lookup_key_(key)));
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -3973,7 +4024,7 @@ class basic_json
|
||||
|
||||
if (is_object())
|
||||
{
|
||||
result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
|
||||
result.m_it.object_iterator = m_value.object->find(std::forward<map_key_type>(to_lookup_key_(key)));
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -4004,7 +4055,7 @@ class basic_json
|
||||
size_type count(KeyT&& key) const
|
||||
{
|
||||
// return 0 for all nonobject types
|
||||
return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
|
||||
return is_object() ? m_value.object->count(std::forward<map_key_type>(to_lookup_key_(key))) : 0;
|
||||
}
|
||||
|
||||
/// @}
|
||||
@ -4909,7 +4960,7 @@ class basic_json
|
||||
{
|
||||
basic_json&& key = init.begin()->moved_or_copied();
|
||||
push_back(typename object_t::value_type(
|
||||
std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
|
||||
std::move(to_map_key_(key.get_ref<string_t&>())), (init.begin() + 1)->moved_or_copied()));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -5014,7 +5065,14 @@ class basic_json
|
||||
}
|
||||
|
||||
// add element to array (perfect forwarding)
|
||||
auto res = m_value.object->emplace(std::forward<Args>(args)...);
|
||||
std::vector<basic_json> args_ = { args... };
|
||||
// we should check for even numbers of args
|
||||
auto res = m_value.object->emplace(to_map_key_(args_[0]), args_[1]);
|
||||
for (auto i = 2; i < args_.size(); i += 2)
|
||||
{
|
||||
m_value.object->emplace(to_map_key_(args_[i]), args_[i + 1]);
|
||||
}
|
||||
|
||||
// create result iterator and set iterator to the result of emplace
|
||||
auto it = begin();
|
||||
it.m_it.object_iterator = res.first;
|
||||
@ -7147,8 +7205,8 @@ class basic_json
|
||||
{
|
||||
return ptr.get_checked(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
@brief remove element from a JSON tree given a pointer
|
||||
|
||||
|
||||
@ -143,7 +143,7 @@ class alt_string
|
||||
str_impl.clear();
|
||||
}
|
||||
|
||||
const value_type* data()
|
||||
const value_type* data() const
|
||||
{
|
||||
return str_impl.data();
|
||||
}
|
||||
@ -155,6 +155,68 @@ class alt_string
|
||||
};
|
||||
|
||||
|
||||
// ---------------------------------
|
||||
|
||||
template<typename R> inline R to_map_key(const alt_string& s);
|
||||
template<typename R> inline R to_lookup_key(const alt_string& s);
|
||||
|
||||
template<>
|
||||
inline std::string to_map_key(const alt_string& s)
|
||||
{
|
||||
return nlohmann::to_map_key<std::string>(std::string(s.data(), s.size()));
|
||||
}
|
||||
template<>
|
||||
inline nlohmann::json_string_view to_map_key(const alt_string& s)
|
||||
{
|
||||
return nlohmann::to_map_key<nlohmann::json_string_view>(std::string(s.data(), s.size()));
|
||||
}
|
||||
template<>
|
||||
inline nlohmann::json_const_char_star to_map_key(const alt_string& s)
|
||||
{
|
||||
return nlohmann::to_map_key<nlohmann::json_const_char_star>(std::string(s.data(), s.size()));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string to_lookup_key(const alt_string& s)
|
||||
{
|
||||
return to_map_key<std::string>(s);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline nlohmann::json_string_view to_lookup_key(const alt_string& s)
|
||||
{
|
||||
return to_map_key<nlohmann::json_string_view>(s);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline nlohmann::json_const_char_star to_lookup_key(const alt_string& s)
|
||||
{
|
||||
return to_map_key<nlohmann::json_const_char_star>(s);
|
||||
}
|
||||
|
||||
// I can't believe this is the right syntax. It works, but by golly!
|
||||
template<>
|
||||
inline alt_string nlohmann::to_concatable_string(const std::string& s)
|
||||
{
|
||||
return alt_string(s.data(), s.size());
|
||||
}
|
||||
|
||||
// I can't believe this is the right syntax. It works, but by golly!
|
||||
template<>
|
||||
inline alt_string nlohmann::to_concatable_string(const nlohmann::json_string_view& s)
|
||||
{
|
||||
return alt_string(s.data(), s.size());
|
||||
}
|
||||
|
||||
// I can't believe this is the right syntax. It works, but by golly!
|
||||
template<>
|
||||
inline alt_string nlohmann::to_concatable_string(const nlohmann::json_const_char_star& s)
|
||||
{
|
||||
return alt_string(s.data, strlen(s.data));
|
||||
}
|
||||
|
||||
// ---------------------------------
|
||||
|
||||
using alt_json = nlohmann::basic_json <
|
||||
std::map,
|
||||
std::vector,
|
||||
|
||||
@ -1076,23 +1076,28 @@ TEST_CASE("constructors")
|
||||
std::string source(1024, '!');
|
||||
const char* source_addr = source.data();
|
||||
|
||||
SECTION("constructor with implicit types (array)")
|
||||
{
|
||||
json j = {std::move(source)};
|
||||
CHECK(j[0].get_ref<std::string const&>().data() == source_addr);
|
||||
}
|
||||
|
||||
SECTION("constructor with implicit types (object)")
|
||||
{
|
||||
json j = {{"key", std::move(source)}};
|
||||
CHECK(j["key"].get_ref<std::string const&>().data() == source_addr);
|
||||
}
|
||||
|
||||
SECTION("constructor with implicit types (object key)")
|
||||
// These are invalid, because if the key type is different from std::string, the pointers will not stay the same
|
||||
// Reenable after templatization of basic_json
|
||||
if (false)
|
||||
{
|
||||
json j = {{std::move(source), 42}};
|
||||
CHECK(j.get_ref<json::object_t&>().begin()->first.data() == source_addr);
|
||||
}
|
||||
SECTION("constructor with implicit types (array)")
|
||||
{
|
||||
json j = {std::move(source)};
|
||||
CHECK(j[0].get_ref<std::string const&>().data() == source_addr);
|
||||
}
|
||||
|
||||
SECTION("constructor with implicit types (object key)")
|
||||
{
|
||||
json j = {{std::move(source), 42}};
|
||||
CHECK(j.get_ref<json::object_t&>().begin()->first.data() == source_addr);
|
||||
}
|
||||
} // end not work
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user