Merge pull request #2553 from jasujm/jasujm/input_adapter_custom_container
Fix compilation of input_adapter(container) in edge cases
This commit is contained in:
commit
ff3863dc1d
@ -371,15 +371,36 @@ typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapte
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convenience shorthand from container to iterator
|
// Convenience shorthand from container to iterator
|
||||||
template<typename ContainerType>
|
// Enables ADL on begin(container) and end(container)
|
||||||
auto input_adapter(const ContainerType& container) -> decltype(input_adapter(begin(container), end(container)))
|
// Encloses the using declarations in namespace for not to leak them to outside scope
|
||||||
{
|
|
||||||
// Enable ADL
|
namespace container_input_adapter_factory_impl {
|
||||||
|
|
||||||
using std::begin;
|
using std::begin;
|
||||||
using std::end;
|
using std::end;
|
||||||
|
|
||||||
|
template<typename ContainerType, typename Enable = void>
|
||||||
|
struct container_input_adapter_factory {};
|
||||||
|
|
||||||
|
template<typename ContainerType>
|
||||||
|
struct container_input_adapter_factory< ContainerType,
|
||||||
|
void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))> >
|
||||||
|
{
|
||||||
|
using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
|
||||||
|
|
||||||
|
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
|
||||||
inline file_input_adapter input_adapter(std::FILE* file)
|
inline file_input_adapter input_adapter(std::FILE* file)
|
||||||
|
@ -5183,15 +5183,36 @@ typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapte
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convenience shorthand from container to iterator
|
// Convenience shorthand from container to iterator
|
||||||
template<typename ContainerType>
|
// Enables ADL on begin(container) and end(container)
|
||||||
auto input_adapter(const ContainerType& container) -> decltype(input_adapter(begin(container), end(container)))
|
// Encloses the using declarations in namespace for not to leak them to outside scope
|
||||||
{
|
|
||||||
// Enable ADL
|
namespace container_input_adapter_factory_impl {
|
||||||
|
|
||||||
using std::begin;
|
using std::begin;
|
||||||
using std::end;
|
using std::end;
|
||||||
|
|
||||||
|
template<typename ContainerType, typename Enable = void>
|
||||||
|
struct container_input_adapter_factory {};
|
||||||
|
|
||||||
|
template<typename ContainerType>
|
||||||
|
struct container_input_adapter_factory< ContainerType,
|
||||||
|
void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))> >
|
||||||
|
{
|
||||||
|
using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
|
||||||
|
|
||||||
|
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
|
||||||
inline file_input_adapter input_adapter(std::FILE* file)
|
inline file_input_adapter input_adapter(std::FILE* file)
|
||||||
|
@ -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")
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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]";
|
||||||
|
Loading…
Reference in New Issue
Block a user