/usr/include/boost/stl_interfaces
Edit: /usr/include/boost/stl_interfaces/view_interface.hpp (7734B)
// 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)
#ifndef BOOST_STL_INTERFACES_VIEW_INTERFACE_HPP
#define BOOST_STL_INTERFACES_VIEW_INTERFACE_HPP
#include
namespace boost { namespace stl_interfaces { inline namespace v1 {
/** A CRTP template that one may derive from to make it easier to define
`std::ranges::view`-like types with a container-like interface. This
is a pre-C++20 version of C++20's `view_interface` (see
[view.interface] in the C++ standard).
The template parameter `D` for `view_interface` may be an incomplete
type. Before any member of the resulting specialization of
`view_interface` other than special member functions is referenced,
`D` shall be complete, and model both
`std::derived_from>` and `std::view`. */
template<
typename Derived,
element_layout Contiguity = element_layout::discontiguous
#ifndef BOOST_STL_INTERFACES_DOXYGEN
,
typename E = std::enable_if_t<
std::is_class::value &&
std::is_same>::value>
#endif
>
struct view_interface;
namespace v1_dtl {
template
void derived_view(view_interface const &);
}
template<
typename Derived,
element_layout Contiguity
#ifndef BOOST_STL_INTERFACES_DOXYGEN
,
typename E
#endif
>
struct view_interface
{
#ifndef BOOST_STL_INTERFACES_DOXYGEN
private:
constexpr Derived & derived() noexcept
{
return static_cast(*this);
}
constexpr const Derived & derived() const noexcept
{
return static_cast(*this);
}
#endif
public:
template
constexpr auto empty() noexcept(
noexcept(std::declval().begin() == std::declval().end()))
-> decltype(
std::declval().begin() == std::declval().end())
{
return derived().begin() == derived().end();
}
template
constexpr auto empty() const noexcept(noexcept(
std::declval().begin() ==
std::declval().end()))
-> decltype(
std::declval().begin() ==
std::declval().end())
{
return derived().begin() == derived().end();
}
template<
typename D = Derived,
typename R = decltype(std::declval().empty())>
constexpr explicit
operator bool() noexcept(noexcept(std::declval().empty()))
{
return !derived().empty();
}
template<
typename D = Derived,
typename R = decltype(std::declval().empty())>
constexpr explicit operator bool() const
noexcept(noexcept(std::declval().empty()))
{
return !derived().empty();
}
template<
typename D = Derived,
element_layout C = Contiguity,
typename Enable = std::enable_if_t>
constexpr auto data() noexcept(noexcept(std::declval().begin()))
-> decltype(std::addressof(*std::declval().begin()))
{
return std::addressof(*derived().begin());
}
template<
typename D = Derived,
element_layout C = Contiguity,
typename Enable = std::enable_if_t>
constexpr auto data() const
noexcept(noexcept(std::declval().begin()))
-> decltype(std::addressof(*std::declval().begin()))
{
return std::addressof(*derived().begin());
}
template
constexpr auto size() noexcept(
noexcept(std::declval().end() - std::declval().begin()))
-> decltype(std::declval().end() - std::declval().begin())
{
return derived().end() - derived().begin();
}
template
constexpr auto size() const noexcept(noexcept(
std::declval().end() -
std::declval().begin()))
-> decltype(
std::declval().end() -
std::declval().begin())
{
return derived().end() - derived().begin();
}
template
constexpr auto front() noexcept(noexcept(*std::declval().begin()))
-> decltype(*std::declval().begin())
{
return *derived().begin();
}
template
constexpr auto front() const
noexcept(noexcept(*std::declval().begin()))
-> decltype(*std::declval().begin())
{
return *derived().begin();
}
template<
typename D = Derived,
typename Enable = std::enable_if_t<
v1_dtl::decrementable_sentinel::value &&
v1_dtl::common_range::value>>
constexpr auto
back() noexcept(noexcept(*std::prev(std::declval().end())))
-> decltype(*std::prev(std::declval().end()))
{
return *std::prev(derived().end());
}
template<
typename D = Derived,
typename Enable = std::enable_if_t<
v1_dtl::decrementable_sentinel::value &&
v1_dtl::common_range::value>>
constexpr auto back() const
noexcept(noexcept(*std::prev(std::declval().end())))
-> decltype(*std::prev(std::declval().end()))
{
return *std::prev(derived().end());
}
template
constexpr auto operator[](v1_dtl::range_difference_t n) noexcept(
noexcept(std::declval().begin()[n]))
-> decltype(std::declval().begin()[n])
{
return derived().begin()[n];
}
template
constexpr auto operator[](v1_dtl::range_difference_t n) const
noexcept(noexcept(std::declval().begin()[n]))
-> decltype(std::declval().begin()[n])
{
return derived().begin()[n];
}
};
/** Implementation of `operator!=()` for all views derived from
`view_interface`. */
template
constexpr auto operator!=(ViewInterface lhs, ViewInterface rhs) noexcept(
noexcept(lhs == rhs))
-> decltype(v1_dtl::derived_view(lhs), !(lhs == rhs))
{
return !(lhs == rhs);
}
}}}
#if 201703L < __cplusplus && defined(__cpp_lib_concepts) || \
defined(BOOST_STL_INTERFACES_DOXYGEN)
#include
namespace boost { namespace stl_interfaces { namespace v2 {
/** A template alias for `std::view_interface`. This only exists to make
migration from Boost.STLInterfaces to C++20 easier; switch to the one
in `std` as soon as you can. */
template
using view_interface = std::ranges::view_interface;
}}}
#endif
#endif