Unverified Commit ff3863dc authored by Niels Lohmann's avatar Niels Lohmann Committed by GitHub

Merge pull request #2553 from jasujm/jasujm/input_adapter_custom_container

Fix compilation of input_adapter(container) in edge cases
parents dfedefb9 467f622c
...@@ -371,14 +371,35 @@ typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapte ...@@ -371,14 +371,35 @@ typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapte
} }
// Convenience shorthand from container to iterator // Convenience shorthand from container to iterator
// Enables ADL on begin(container) and end(container)
// Encloses the using declarations in namespace for not to leak them to outside scope
namespace container_input_adapter_factory_impl {
using std::begin;
using std::end;
template<typename ContainerType, typename Enable = void>
struct container_input_adapter_factory {};
template<typename ContainerType> template<typename ContainerType>
auto input_adapter(const ContainerType& container) -> decltype(input_adapter(begin(container), end(container))) struct container_input_adapter_factory< ContainerType,
void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))> >
{ {
// Enable ADL using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
using std::begin;
using std::end; static adapter_type create(const ContainerType& container)
{
return input_adapter(begin(container), end(container));
}
};
}
return input_adapter(begin(container), end(container)); template<typename ContainerType>
typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)
{
return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);
} }
// Special cases with fast paths // Special cases with fast paths
......
...@@ -5183,14 +5183,35 @@ typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapte ...@@ -5183,14 +5183,35 @@ typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapte
} }
// Convenience shorthand from container to iterator // Convenience shorthand from container to iterator
// Enables ADL on begin(container) and end(container)
// Encloses the using declarations in namespace for not to leak them to outside scope
namespace container_input_adapter_factory_impl {
using std::begin;
using std::end;
template<typename ContainerType, typename Enable = void>
struct container_input_adapter_factory {};
template<typename ContainerType> template<typename ContainerType>
auto input_adapter(const ContainerType& container) -> decltype(input_adapter(begin(container), end(container))) struct container_input_adapter_factory< ContainerType,
void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))> >
{ {
// Enable ADL using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
using std::begin;
using std::end; static adapter_type create(const ContainerType& container)
{
return input_adapter(begin(container), end(container));
}
};
return input_adapter(begin(container), end(container)); }
template<typename ContainerType>
typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)
{
return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);
} }
// Special cases with fast paths // Special cases with fast paths
...@@ -16801,7 +16822,7 @@ class basic_json ...@@ -16801,7 +16822,7 @@ class basic_json
detail::parser_callback_t<basic_json>cb = nullptr, detail::parser_callback_t<basic_json>cb = nullptr,
const bool allow_exceptions = true, const bool allow_exceptions = true,
const bool ignore_comments = false const bool ignore_comments = false
) )
{ {
return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter), return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
std::move(cb), allow_exceptions, ignore_comments); std::move(cb), allow_exceptions, ignore_comments);
...@@ -25346,7 +25367,7 @@ template<> ...@@ -25346,7 +25367,7 @@ template<>
inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept( inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
is_nothrow_move_constructible<nlohmann::json>::value&& is_nothrow_move_constructible<nlohmann::json>::value&&
is_nothrow_move_assignable<nlohmann::json>::value is_nothrow_move_assignable<nlohmann::json>::value
) )
{ {
j1.swap(j2); j1.swap(j2);
} }
......
...@@ -63,7 +63,7 @@ const char* end(const MyContainer& c) ...@@ -63,7 +63,7 @@ const char* end(const MyContainer& c)
return c.data + strlen(c.data); return c.data + strlen(c.data);
} }
TEST_CASE("Custom container") TEST_CASE("Custom container non-member begin/end")
{ {
MyContainer data{"[1,2,3,4]"}; MyContainer data{"[1,2,3,4]"};
...@@ -75,6 +75,31 @@ TEST_CASE("Custom container") ...@@ -75,6 +75,31 @@ TEST_CASE("Custom container")
} }
TEST_CASE("Custom container member begin/end")
{
struct MyContainer2
{
const char* data;
const char* begin() const
{
return data;
}
const char* end() const
{
return data + strlen(data);
}
};
MyContainer2 data{"[1,2,3,4]"};
json as_json = json::parse(data);
CHECK(as_json.at(0) == 1);
CHECK(as_json.at(1) == 2);
CHECK(as_json.at(2) == 3);
CHECK(as_json.at(3) == 4);
}
TEST_CASE("Custom iterator") TEST_CASE("Custom iterator")
{ {
const char* raw_data = "[1,2,3,4]"; const char* raw_data = "[1,2,3,4]";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment