diff --git a/include/boost/stl_interfaces/container_interface.hpp b/include/boost/stl_interfaces/container_interface.hpp index c2ac852..feb5104 100644 --- a/include/boost/stl_interfaces/container_interface.hpp +++ b/include/boost/stl_interfaces/container_interface.hpp @@ -12,18 +12,8 @@ namespace boost { namespace stl_interfaces { namespace detail { - template - struct has_reserve : std::false_type - { - }; - template - struct has_reserve().reserve())>> - : std::true_type - { - }; - template - struct n_iter : boost::stl_interfaces::iterator_interface< + struct n_iter : iterator_interface< n_iter, std::random_access_iterator_tag, T> @@ -42,7 +32,7 @@ namespace boost { namespace stl_interfaces { } private: - friend boost::stl_interfaces::access; + friend access; constexpr T const *& base_reference() noexcept { return x_; } constexpr T const * base_reference() const noexcept { return x_; } @@ -54,7 +44,10 @@ namespace boost { namespace stl_interfaces { constexpr auto make_n_iter(T const & x, SizeType n) noexcept( noexcept(n_iter(x, n))) { - return n_iter(x, SizeType(0)); + using result_type = n_iter; + BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT( + result_type, std::random_access_iterator) + return result_type(x, SizeType(0)); } template constexpr auto make_n_iter_end(T const & x, SizeType n) noexcept( diff --git a/include/boost/stl_interfaces/fwd.hpp b/include/boost/stl_interfaces/fwd.hpp index 85d68a0..974adda 100644 --- a/include/boost/stl_interfaces/fwd.hpp +++ b/include/boost/stl_interfaces/fwd.hpp @@ -55,11 +55,9 @@ namespace boost { namespace stl_interfaces { template struct sentinel; template - struct sentinel< - Range, - void_t().begin())>> + struct sentinel().end())>> { - using type = decltype(std::declval().begin()); + using type = decltype(std::declval().end()); }; template using sentinel_t = typename sentinel::type; diff --git a/include/boost/stl_interfaces/reverse_iterator.hpp b/include/boost/stl_interfaces/reverse_iterator.hpp index bd81bf5..7a65345 100644 --- a/include/boost/stl_interfaces/reverse_iterator.hpp +++ b/include/boost/stl_interfaces/reverse_iterator.hpp @@ -11,7 +11,6 @@ namespace boost { namespace stl_interfaces { - // TODO: Tests. // TODO: Look in all the headers for ADL traps. /** This type is very similar to the C++20 version of @@ -19,7 +18,7 @@ namespace boost { namespace stl_interfaces { proxy-friendly. */ template struct reverse_iterator - : boost::stl_interfaces::iterator_interface< + : iterator_interface< reverse_iterator, #if 201703L < __cplusplus && defined(__cpp_lib_ranges) typename std::iterator_traits::iterator_concept, @@ -75,7 +74,7 @@ namespace boost { namespace stl_interfaces { } private: - friend boost::stl_interfaces::access; + friend access; constexpr BidiIter & base_reference() noexcept { return it_; } constexpr BidiIter const & base_reference() const noexcept { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0a110c5..0f467b7 100755 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -46,3 +46,4 @@ add_test_executable(forward) add_test_executable(bidirectional) add_test_executable(random_access) add_test_executable(reverse_iter) +add_test_executable(detail) diff --git a/test/detail.cpp b/test/detail.cpp new file mode 100644 index 0000000..3aed466 --- /dev/null +++ b/test/detail.cpp @@ -0,0 +1,82 @@ +// Copyright (C) 2019 T. Zachary Laine +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#include +#include +#include + +#include + +#include + +#include +#include + + +namespace detail = boost::stl_interfaces::detail; + + +// iter_difference_t +BOOST_MPL_ASSERT( + (std::is_same, std::ptrdiff_t>)); +BOOST_MPL_ASSERT((std::is_same< + detail::iter_difference_t::iterator>, + std::vector::difference_type>)); +BOOST_MPL_ASSERT((std::is_same< + detail::iter_difference_t::iterator>, + std::list::difference_type>)); + +struct ridiculous_range +{ + int * begin() { return nullptr; } + double end() { return 1.3; } +}; + +// iterator_t +BOOST_MPL_ASSERT((std::is_same< + detail::iterator_t>, + std::vector::iterator>)); +BOOST_MPL_ASSERT((std::is_same< + detail::iterator_t>, + std::list::iterator>)); +BOOST_MPL_ASSERT((std::is_same, int *>)); + +// sentinel_t +BOOST_MPL_ASSERT((std::is_same< + detail::sentinel_t>, + std::vector::iterator>)); +BOOST_MPL_ASSERT((std::is_same< + detail::sentinel_t>, + std::list::iterator>)); +BOOST_MPL_ASSERT((std::is_same, double>)); + +// range_difference_t +BOOST_MPL_ASSERT( + (std::is_same< + detail::range_difference_t>, + std::iterator_traits::iterator>::difference_type>)); +BOOST_MPL_ASSERT( + (std::is_same< + detail::range_difference_t>, + std::iterator_traits::iterator>::difference_type>)); +BOOST_MPL_ASSERT((std::is_same< + detail::range_difference_t, + std::ptrdiff_t>)); + +// common_range +static_assert(detail::common_range>::value, ""); +static_assert(detail::common_range>::value, ""); +static_assert(!detail::common_range::value, ""); + + +TEST(detail, n_iter) +{ + std::array ints = {{0, 1, 2, 3, 4}}; + int const new_value = 6; + detail::n_iter first = detail::make_n_iter(new_value, 3); + detail::n_iter last = detail::make_n_iter_end(new_value, 3); + std::copy(first, last, &ints[1]); + EXPECT_EQ(ints, (std::array{0, 6, 6, 6, 4})); +}