Make element_type an enum class; bool Contiguous -> element_type Contiguity in {view,container}_interface.

Fixes #14.
This commit is contained in:
Zach Laine
2019-12-31 11:45:18 -06:00
parent f0dc49747f
commit e55bb9ffdb
11 changed files with 119 additions and 80 deletions

View File

@@ -337,12 +337,12 @@ types your derived view type define.
Here is the declaration of _view_iface_:
template<typename Derived, bool Contiguous = discontiguous>
template<typename Derived, element_layout Contiguity = element_layout::discontiguous>
struct view_interface;
_view_iface_ only requires the derived type and an optional `bool` non-type
template parameter that indicates whether `Derived`'s iterators are
contiguous. The `bool` parameter is necessary to support pre-C++20 code.
_view_iface_ only requires the derived type and an optional non-type template
parameter that indicates whether `Derived`'s iterators are contiguous. The
non-type parameter is necessary to support pre-C++20 code.
[note Proxy iterators are inherently discontiguous.]
@@ -393,13 +393,12 @@ _cont_iface_ exists to make bring that large development time way, way down.
Here is its declaration:
template<typename Derived, bool Contiguous = discontiguous>
template<typename Derived, element_layout Contiguity = element_layout::discontiguous>
struct container_interface;
Just as with _view_iface_, _cont_iface_ takes the derived type and an optional
`bool` non-type template parameter that indicates whether `Derived`'s
iterators are contiguous. The `bool` parameter is necessary to support
pre-C++20 code.
non-type template parameter that indicates whether `Derived`'s iterators are
contiguous. The non-type parameter is necessary to support pre-C++20 code.
The tables below represent a subset of the operations needed for each of the
container requirements tables in the standard. _cont_iface_ covers the
@@ -944,7 +943,7 @@ subtle, and will not be noticeable.
Differences you will probably notice:
- _view_iface_ and _cont_iface_ each have a `bool` non-type template parameter
- _view_iface_ and _cont_iface_ each have a non-type template parameter
`Contiguous` that indicates whether they have a `begin()` operation that
yields a contiguous iterator. Before C++20, there was no way of determining
that. The `v2` versions do not need this template parameter.

View File

@@ -16,13 +16,13 @@
// C++14 version (v1::) of container_interface gets used, or the C++20 version
// (v2::).
#if defined(USE_V2)
template<typename Derived, bool Contiguous>
template<typename Derived, boost::stl_interfaces::element_layout Contiguity>
using container_interface =
boost::stl_interfaces::v2::container_interface<Derived>;
#else
template<typename Derived, bool Contiguous>
template<typename Derived, boost::stl_interfaces::element_layout Contiguity>
using container_interface =
boost::stl_interfaces::v1::container_interface<Derived, Contiguous>;
boost::stl_interfaces::v1::container_interface<Derived, Contiguity>;
#endif
@@ -38,7 +38,7 @@ using container_interface =
template<typename T, std::size_t N>
struct static_vector : container_interface<
static_vector<T, N>,
boost::stl_interfaces::contiguous>
boost::stl_interfaces::element_layout::contiguous>
{
// These are the types required for reversible containers. These must be
// user-defined.
@@ -250,7 +250,7 @@ struct static_vector : container_interface<
// using declarations here.
using base_type = container_interface<
static_vector<T, N>,
boost::stl_interfaces::contiguous>;
boost::stl_interfaces::element_layout::contiguous>;
using base_type::begin;
using base_type::end;
using base_type::resize;

View File

@@ -97,7 +97,7 @@ namespace boost { namespace stl_interfaces { inline namespace v1 {
std::ranges::end(d))`. */
template<
typename Derived,
bool Contiguous = discontiguous
element_layout Contiguity = element_layout::discontiguous
#ifndef BOOST_STL_INTERFACES_DOXYGEN
,
typename E = std::enable_if_t<
@@ -124,13 +124,13 @@ namespace boost { namespace stl_interfaces { inline namespace v1 {
static constexpr void call(D & d) noexcept { d.clear(); }
};
template<typename D, bool Contiguous>
void derived_container(container_interface<D, Contiguous> const &);
template<typename D, element_layout Contiguity>
void derived_container(container_interface<D, Contiguity> const &);
}
template<
typename Derived,
bool Contiguous
element_layout Contiguity
#ifndef BOOST_STL_INTERFACES_DOXYGEN
,
typename E
@@ -176,8 +176,8 @@ namespace boost { namespace stl_interfaces { inline namespace v1 {
template<
typename D = Derived,
bool C = Contiguous,
typename Enable = std::enable_if_t<C>>
element_layout C = Contiguity,
typename Enable = std::enable_if_t<C == element_layout::contiguous>>
constexpr auto data() noexcept(noexcept(std::declval<D &>().begin()))
-> decltype(std::addressof(*std::declval<D &>().begin()))
{
@@ -185,8 +185,8 @@ namespace boost { namespace stl_interfaces { inline namespace v1 {
}
template<
typename D = Derived,
bool C = Contiguous,
typename Enable = std::enable_if_t<C>>
element_layout C = Contiguity,
typename Enable = std::enable_if_t<C == element_layout::contiguous>>
constexpr auto data() const
noexcept(noexcept(std::declval<D const &>().begin()))
-> decltype(std::addressof(*std::declval<D const &>().begin()))

View File

@@ -36,9 +36,12 @@ namespace boost { namespace stl_interfaces {
inline namespace v1 {
/** An enumeration used to indicate whether the underlying data have a
contiguous layout when instantiating `view_interface` and
`container_interface`. */
enum element_layout : bool { discontiguous = false, contiguous = true };
contiguous or discontiguous layout when instantiating
`view_interface` and `container_interface`. */
enum class element_layout : bool {
discontiguous = false,
contiguous = true
};
namespace v1_dtl {
template<typename... T>

View File

@@ -23,7 +23,7 @@ namespace boost { namespace stl_interfaces { inline namespace v1 {
`std::derived_from<view_interface<D>>` and `std::view`. */
template<
typename Derived,
bool Contiguous = discontiguous
element_layout Contiguity = element_layout::discontiguous
#ifndef BOOST_STL_INTERFACES_DOXYGEN
,
typename E = std::enable_if_t<
@@ -34,13 +34,13 @@ namespace boost { namespace stl_interfaces { inline namespace v1 {
struct view_interface;
namespace v1_dtl {
template<typename D, bool Contiguous>
void derived_view(view_interface<D, Contiguous> const &);
template<typename D, element_layout Contiguity>
void derived_view(view_interface<D, Contiguity> const &);
}
template<
typename Derived,
bool Contiguous
element_layout Contiguity
#ifndef BOOST_STL_INTERFACES_DOXYGEN
,
typename E
@@ -99,8 +99,8 @@ namespace boost { namespace stl_interfaces { inline namespace v1 {
template<
typename D = Derived,
bool C = Contiguous,
typename Enable = std::enable_if_t<C>>
element_layout C = Contiguity,
typename Enable = std::enable_if_t<C == element_layout::contiguous>>
constexpr auto data() noexcept(noexcept(std::declval<D &>().begin()))
-> decltype(std::addressof(*std::declval<D &>().begin()))
{
@@ -108,8 +108,8 @@ namespace boost { namespace stl_interfaces { inline namespace v1 {
}
template<
typename D = Derived,
bool C = Contiguous,
typename Enable = std::enable_if_t<C>>
element_layout C = Contiguity,
typename Enable = std::enable_if_t<C == element_layout::contiguous>>
constexpr auto data() const
noexcept(noexcept(std::declval<D const &>().begin()))
-> decltype(std::addressof(*std::declval<D const &>().begin()))

View File

@@ -17,9 +17,9 @@
// Just like std::array, except for the 0-size specialization, and the fact
// that the base class makes brace-initialization wonky.
template<typename T, std::size_t N>
struct array
: boost::stl_interfaces::
container_interface<array<T, N>, boost::stl_interfaces::contiguous>
struct array : boost::stl_interfaces::container_interface<
array<T, N>,
boost::stl_interfaces::v1::element_layout::contiguous>
{
using value_type = T;
using pointer = T *;
@@ -50,8 +50,9 @@ struct array
}
}
using base_type = boost::stl_interfaces::
container_interface<array<T, N>, boost::stl_interfaces::contiguous>;
using base_type = boost::stl_interfaces::container_interface<
array<T, N>,
boost::stl_interfaces::v1::element_layout::contiguous>;
using base_type::begin;
using base_type::end;

View File

@@ -103,7 +103,8 @@ struct basic_adapted_bidirectional_list_iter
int>
{
basic_adapted_bidirectional_list_iter() : it_() {}
basic_adapted_bidirectional_list_iter(std::list<int>::iterator it) : it_(it) {}
basic_adapted_bidirectional_list_iter(std::list<int>::iterator it) : it_(it)
{}
private:
friend boost::stl_interfaces::access;
@@ -561,7 +562,7 @@ static_assert(
subrange<
basic_bidirectional_iter,
basic_bidirectional_iter,
boost::stl_interfaces::v1::discontiguous>>::value,
boost::stl_interfaces::v1::element_layout::discontiguous>>::value,
"");
static_assert(
ill_formed<
@@ -569,7 +570,8 @@ static_assert(
subrange<
basic_bidirectional_iter,
basic_bidirectional_iter,
boost::stl_interfaces::v1::discontiguous> const>::value,
boost::stl_interfaces::v1::element_layout::discontiguous> const>::
value,
"");
template<typename T>
@@ -581,7 +583,7 @@ static_assert(
subrange<
basic_bidirectional_iter,
basic_bidirectional_iter,
boost::stl_interfaces::v1::discontiguous>>::value,
boost::stl_interfaces::v1::element_layout::discontiguous>>::value,
"");
static_assert(
ill_formed<
@@ -589,7 +591,8 @@ static_assert(
subrange<
basic_bidirectional_iter,
basic_bidirectional_iter,
boost::stl_interfaces::v1::discontiguous> const>::value,
boost::stl_interfaces::v1::element_layout::discontiguous> const>::
value,
"");
template<typename T>
@@ -601,7 +604,7 @@ static_assert(
subrange<
basic_bidirectional_iter,
basic_bidirectional_iter,
boost::stl_interfaces::v1::discontiguous>>::value,
boost::stl_interfaces::v1::element_layout::discontiguous>>::value,
"");
static_assert(
ill_formed<
@@ -609,7 +612,8 @@ static_assert(
subrange<
basic_bidirectional_iter,
basic_bidirectional_iter,
boost::stl_interfaces::v1::discontiguous> const>::value,
boost::stl_interfaces::v1::element_layout::discontiguous> const>::
value,
"");
TEST(bidirectional, basic_subrange)
@@ -617,8 +621,11 @@ TEST(bidirectional, basic_subrange)
basic_bidirectional_iter first(ints.data());
basic_bidirectional_iter last(ints.data() + ints.size());
auto r = range<boost::stl_interfaces::v1::discontiguous>(first, last);
auto empty = range<boost::stl_interfaces::v1::discontiguous>(first, first);
auto r = range<boost::stl_interfaces::v1::element_layout::discontiguous>(
first, last);
auto empty =
range<boost::stl_interfaces::v1::element_layout::discontiguous>(
first, first);
// range begin/end
{

View File

@@ -216,7 +216,7 @@ static_assert(
subrange<
basic_forward_iter,
basic_forward_iter,
boost::stl_interfaces::v1::discontiguous>>::value,
boost::stl_interfaces::v1::element_layout::discontiguous>>::value,
"");
static_assert(
ill_formed<
@@ -224,7 +224,8 @@ static_assert(
subrange<
basic_forward_iter,
basic_forward_iter,
boost::stl_interfaces::v1::discontiguous> const>::value,
boost::stl_interfaces::v1::element_layout::discontiguous> const>::
value,
"");
template<typename T>
@@ -236,7 +237,7 @@ static_assert(
subrange<
basic_forward_iter,
basic_forward_iter,
boost::stl_interfaces::v1::discontiguous>>::value,
boost::stl_interfaces::v1::element_layout::discontiguous>>::value,
"");
static_assert(
ill_formed<
@@ -244,7 +245,8 @@ static_assert(
subrange<
basic_forward_iter,
basic_forward_iter,
boost::stl_interfaces::v1::discontiguous> const>::value,
boost::stl_interfaces::v1::element_layout::discontiguous> const>::
value,
"");
template<typename T>
@@ -256,7 +258,7 @@ static_assert(
subrange<
basic_forward_iter,
basic_forward_iter,
boost::stl_interfaces::v1::discontiguous>>::value,
boost::stl_interfaces::v1::element_layout::discontiguous>>::value,
"");
static_assert(
ill_formed<
@@ -264,7 +266,8 @@ static_assert(
subrange<
basic_forward_iter,
basic_forward_iter,
boost::stl_interfaces::v1::discontiguous> const>::value,
boost::stl_interfaces::v1::element_layout::discontiguous> const>::
value,
"");
template<typename T>
@@ -276,7 +279,7 @@ static_assert(
subrange<
basic_forward_iter,
basic_forward_iter,
boost::stl_interfaces::v1::discontiguous>>::value,
boost::stl_interfaces::v1::element_layout::discontiguous>>::value,
"");
static_assert(
ill_formed<
@@ -284,7 +287,8 @@ static_assert(
subrange<
basic_forward_iter,
basic_forward_iter,
boost::stl_interfaces::v1::discontiguous> const>::value,
boost::stl_interfaces::v1::element_layout::discontiguous> const>::
value,
"");
TEST(forward, basic_subrange)
@@ -292,8 +296,11 @@ TEST(forward, basic_subrange)
basic_forward_iter first(ints.data());
basic_forward_iter last(ints.data() + ints.size());
auto r = range<boost::stl_interfaces::v1::discontiguous>(first, last);
auto empty = range<boost::stl_interfaces::v1::discontiguous>(first, first);
auto r = range<boost::stl_interfaces::v1::element_layout::discontiguous>(
first, last);
auto empty =
range<boost::stl_interfaces::v1::element_layout::discontiguous>(
first, first);
// range begin/end
{

View File

@@ -297,7 +297,7 @@ static_assert(
subrange<
basic_input_iter,
basic_input_iter,
boost::stl_interfaces::v1::discontiguous>>::value,
boost::stl_interfaces::v1::element_layout::discontiguous>>::value,
"");
static_assert(
ill_formed<
@@ -305,7 +305,8 @@ static_assert(
subrange<
basic_input_iter,
basic_input_iter,
boost::stl_interfaces::v1::discontiguous> const>::value,
boost::stl_interfaces::v1::element_layout::discontiguous> const>::
value,
"");
template<typename T>
@@ -317,7 +318,7 @@ static_assert(
subrange<
basic_input_iter,
basic_input_iter,
boost::stl_interfaces::v1::discontiguous>>::value,
boost::stl_interfaces::v1::element_layout::discontiguous>>::value,
"");
static_assert(
ill_formed<
@@ -325,7 +326,8 @@ static_assert(
subrange<
basic_input_iter,
basic_input_iter,
boost::stl_interfaces::v1::discontiguous> const>::value,
boost::stl_interfaces::v1::element_layout::discontiguous> const>::
value,
"");
template<typename T>
@@ -337,7 +339,7 @@ static_assert(
subrange<
basic_input_iter,
basic_input_iter,
boost::stl_interfaces::v1::discontiguous>>::value,
boost::stl_interfaces::v1::element_layout::discontiguous>>::value,
"");
static_assert(
ill_formed<
@@ -345,7 +347,8 @@ static_assert(
subrange<
basic_input_iter,
basic_input_iter,
boost::stl_interfaces::v1::discontiguous> const>::value,
boost::stl_interfaces::v1::element_layout::discontiguous> const>::
value,
"");
template<typename T>
@@ -357,7 +360,7 @@ static_assert(
subrange<
basic_input_iter,
basic_input_iter,
boost::stl_interfaces::v1::discontiguous>>::value,
boost::stl_interfaces::v1::element_layout::discontiguous>>::value,
"");
static_assert(
ill_formed<
@@ -365,7 +368,8 @@ static_assert(
subrange<
basic_input_iter,
basic_input_iter,
boost::stl_interfaces::v1::discontiguous> const>::value,
boost::stl_interfaces::v1::element_layout::discontiguous> const>::
value,
"");
TEST(input, basic_subrange)
@@ -373,8 +377,11 @@ TEST(input, basic_subrange)
basic_input_iter first(ints.data());
basic_input_iter last(ints.data() + ints.size());
auto r = range<boost::stl_interfaces::v1::discontiguous>(first, last);
auto empty = range<boost::stl_interfaces::v1::discontiguous>(first, first);
auto r = range<boost::stl_interfaces::v1::element_layout::discontiguous>(
first, last);
auto empty =
range<boost::stl_interfaces::v1::element_layout::discontiguous>(
first, first);
// range begin/end
{

View File

@@ -838,7 +838,7 @@ static_assert(
subrange<
basic_random_access_iter,
basic_random_access_iter,
boost::stl_interfaces::v1::discontiguous>>::value,
boost::stl_interfaces::v1::element_layout::discontiguous>>::value,
"");
static_assert(
ill_formed<
@@ -846,7 +846,8 @@ static_assert(
subrange<
basic_random_access_iter,
basic_random_access_iter,
boost::stl_interfaces::v1::discontiguous> const>::value,
boost::stl_interfaces::v1::element_layout::discontiguous> const>::
value,
"");
template<typename T>
@@ -855,8 +856,10 @@ using back_t = decltype(std::declval<T>().back());
static_assert(
ill_formed<
back_t,
subrange<int *, int const *, boost::stl_interfaces::v1::discontiguous>>::
value,
subrange<
int *,
int const *,
boost::stl_interfaces::v1::element_layout::discontiguous>>::value,
"");
static_assert(
ill_formed<
@@ -864,7 +867,8 @@ static_assert(
subrange<
int *,
int const *,
boost::stl_interfaces::v1::discontiguous> const>::value,
boost::stl_interfaces::v1::element_layout::discontiguous> const>::
value,
"");
TEST(random_access, basic_subrange)
@@ -872,8 +876,10 @@ TEST(random_access, basic_subrange)
basic_random_access_iter first(ints.data());
basic_random_access_iter last(ints.data() + ints.size());
auto r = range<boost::stl_interfaces::contiguous>(first, last);
auto empty = range<boost::stl_interfaces::contiguous>(first, first);
auto r = range<boost::stl_interfaces::v1::element_layout::contiguous>(
first, last);
auto empty = range<boost::stl_interfaces::v1::element_layout::contiguous>(
first, first);
// range begin/end
{
@@ -953,8 +959,11 @@ TEST(random_access, zip_subrange)
zip_iter first(ints.data(), ones.data());
zip_iter last(ints.data() + ints.size(), ones.data() + ones.size());
auto r = range<boost::stl_interfaces::v1::discontiguous>(first, last);
auto empty = range<boost::stl_interfaces::v1::discontiguous>(first, first);
auto r = range<boost::stl_interfaces::v1::element_layout::discontiguous>(
first, last);
auto empty =
range<boost::stl_interfaces::v1::element_layout::discontiguous>(
first, first);
// range begin/end
{

View File

@@ -9,10 +9,13 @@
#include <boost/stl_interfaces/view_interface.hpp>
template<typename Iterator, typename Sentinel, bool Contiguous>
template<
typename Iterator,
typename Sentinel,
boost::stl_interfaces::element_layout Contiguity>
struct subrange
: boost::stl_interfaces::
view_interface<subrange<Iterator, Sentinel, Contiguous>, Contiguous>
view_interface<subrange<Iterator, Sentinel, Contiguity>, Contiguity>
{
subrange() = default;
constexpr subrange(Iterator it, Sentinel s) : first_(it), last_(s) {}
@@ -25,10 +28,13 @@ private:
Sentinel last_;
};
template<bool Contiguous, typename Iterator, typename Sentinel>
template<
boost::stl_interfaces::element_layout Contiguity,
typename Iterator,
typename Sentinel>
auto range(Iterator i, Sentinel s)
{
return subrange<Iterator, Sentinel, Contiguous>(i, s);
return subrange<Iterator, Sentinel, Contiguity>(i, s);
}
#endif