Allow items() to be used with custom string

This commit is contained in:
Julien Hamaide 2019-09-26 13:13:01 +02:00
parent 99d7518d21
commit 0f073e26eb
3 changed files with 52 additions and 8 deletions

View file

@ -12,6 +12,10 @@ namespace nlohmann
{ {
namespace detail namespace detail
{ {
void int_to_string( std::string& target, int value )
{
target = std::to_string(value);
}
template <typename IteratorType> class iteration_proxy_value template <typename IteratorType> class iteration_proxy_value
{ {
public: public:
@ -20,6 +24,7 @@ template <typename IteratorType> class iteration_proxy_value
using pointer = value_type * ; using pointer = value_type * ;
using reference = value_type & ; using reference = value_type & ;
using iterator_category = std::input_iterator_tag; using iterator_category = std::input_iterator_tag;
using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
private: private:
/// the iterator /// the iterator
@ -29,9 +34,9 @@ template <typename IteratorType> class iteration_proxy_value
/// last stringified array index /// last stringified array index
mutable std::size_t array_index_last = 0; mutable std::size_t array_index_last = 0;
/// a string representation of the array index /// a string representation of the array index
mutable std::string array_index_str = "0"; mutable string_type array_index_str = "0";
/// an empty string (to return a reference for primitive values) /// an empty string (to return a reference for primitive values)
const std::string empty_str = ""; const string_type empty_str = "";
public: public:
explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {} explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
@ -64,7 +69,7 @@ template <typename IteratorType> class iteration_proxy_value
} }
/// return key of the iterator /// return key of the iterator
const std::string& key() const const string_type& key() const
{ {
assert(anchor.m_object != nullptr); assert(anchor.m_object != nullptr);
@ -75,7 +80,7 @@ template <typename IteratorType> class iteration_proxy_value
{ {
if (array_index != array_index_last) if (array_index != array_index_last)
{ {
array_index_str = std::to_string(array_index); int_to_string( array_index_str, array_index );
array_index_last = array_index; array_index_last = array_index;
} }
return array_index_str; return array_index_str;

View file

@ -3186,6 +3186,10 @@ namespace nlohmann
{ {
namespace detail namespace detail
{ {
void int_to_string( std::string& target, int value )
{
target = std::to_string(value);
}
template <typename IteratorType> class iteration_proxy_value template <typename IteratorType> class iteration_proxy_value
{ {
public: public:
@ -3194,6 +3198,7 @@ template <typename IteratorType> class iteration_proxy_value
using pointer = value_type * ; using pointer = value_type * ;
using reference = value_type & ; using reference = value_type & ;
using iterator_category = std::input_iterator_tag; using iterator_category = std::input_iterator_tag;
using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
private: private:
/// the iterator /// the iterator
@ -3203,9 +3208,9 @@ template <typename IteratorType> class iteration_proxy_value
/// last stringified array index /// last stringified array index
mutable std::size_t array_index_last = 0; mutable std::size_t array_index_last = 0;
/// a string representation of the array index /// a string representation of the array index
mutable std::string array_index_str = "0"; mutable string_type array_index_str = "0";
/// an empty string (to return a reference for primitive values) /// an empty string (to return a reference for primitive values)
const std::string empty_str = ""; const string_type empty_str = "";
public: public:
explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {} explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
@ -3238,7 +3243,7 @@ template <typename IteratorType> class iteration_proxy_value
} }
/// return key of the iterator /// return key of the iterator
const std::string& key() const const string_type& key() const
{ {
assert(anchor.m_object != nullptr); assert(anchor.m_object != nullptr);
@ -3249,7 +3254,7 @@ template <typename IteratorType> class iteration_proxy_value
{ {
if (array_index != array_index_last) if (array_index != array_index_last)
{ {
array_index_str = std::to_string(array_index); int_to_string( array_index_str, array_index );
array_index_last = array_index; array_index_last = array_index;
} }
return array_index_str; return array_index_str;

View file

@ -154,6 +154,11 @@ class alt_string
friend bool ::operator<(const char*, const alt_string&); friend bool ::operator<(const char*, const alt_string&);
}; };
void int_to_string( alt_string& target, int value )
{
target = std::to_string(value).c_str();
}
using alt_json = nlohmann::basic_json < using alt_json = nlohmann::basic_json <
std::map, std::map,
std::vector, std::vector,
@ -232,6 +237,35 @@ TEST_CASE("alternative string type")
CHECK(dump == R"({"foo":"bar"})"); CHECK(dump == R"({"foo":"bar"})");
} }
SECTION("items")
{
auto doc = alt_json::parse("{\"foo\": \"bar\"}");
for ( auto item : doc.items() )
{
CHECK( item.key() == "foo" );
CHECK( item.value() == "bar" );
}
auto doc_array = alt_json::parse("[\"foo\", \"bar\"]");
for ( auto item : doc_array.items() )
{
if (item.key() == "0" )
{
CHECK( item.value() == "foo" );
}
else if (item.key() == "1" )
{
CHECK( item.value() == "bar" );
}
else
{
CHECK( false );
}
}
}
SECTION("equality") SECTION("equality")
{ {
alt_json doc; alt_json doc;