view: add yet more constructors

This commit is contained in:
Danny Robson 2017-12-30 13:40:37 +11:00
parent 0f450b5b1c
commit dc010d87be

119
view.hpp
View File

@ -48,7 +48,12 @@ namespace util {
//---------------------------------------------------------------------
template <typename CountT, typename = std::enable_if_t<std::is_integral_v<CountT>,void>>
// cosntruction from pointer/size represenations for ease of use with
// legacy C code.
template <
typename CountT,
typename = std::enable_if_t<std::is_integral_v<CountT>,void>
>
view (
const BeginT &_begin,
CountT _size
@ -58,6 +63,7 @@ namespace util {
//---------------------------------------------------------------------
// implicit conversion from pointer views to const pointer views
template <
typename ValueT,
typename = std::enable_if_t<
@ -76,21 +82,51 @@ namespace util {
// accidentally include the trailing null in the data.
template <std::size_t N>
view (const char (&value)[N]):
view (std::begin (value), std::begin (value) + N - 1)
view {std::begin (value), std::begin (value) + N - 1}
{
static_assert (N > 0);
}
//---------------------------------------------------------------------
view (const char *str):
view { str, str + strlen (str) }
{ ; }
//---------------------------------------------------------------------
view (char *str):
view (str, str + strlen (str))
{ ; }
//---------------------------------------------------------------------
template <std::size_t N>
view (char (&value)[N]):
view {std::begin (value), std::begin (value) + N - 1}
{
static_assert (N > 0);
}
//---------------------------------------------------------------------
template <std::size_t N, typename ValueT>
view (const ValueT(&value)[N]):
view (std::begin (value), std::end (value))
view {std::begin (value), std::end (value)}
{ ; }
//---------------------------------------------------------------------
template <std::size_t N, typename ValueT>
view (ValueT(&value)[N]):
view {std::begin (value), std::end (value)}
{ ; }
//---------------------------------------------------------------------
constexpr
view (const view &rhs) noexcept:
view (rhs.m_begin, rhs.m_end)
view {rhs.m_begin, rhs.m_end}
{ ; }
@ -100,7 +136,7 @@ namespace util {
// class as a base for unique owning pointers without exposing the
// begin/end data members to them directly.
constexpr view (view &&rhs) noexcept:
view (std::move (rhs.m_begin), std::move (rhs.m_end))
view {std::move (rhs.m_begin), std::move (rhs.m_end)}
{ ; }
@ -124,33 +160,23 @@ namespace util {
//---------------------------------------------------------------------
// non-contigous containers should use their begin/end iterators
// directly
template <
typename ContainerT,
typename std::enable_if_t<!is_contiguous_v<ContainerT>,ContainerT*> = nullptr
>
constexpr explicit
view (
ContainerT &klass
):
view (std::begin (klass), std::end (klass))
template <typename CharT, typename Traits, typename Allocator>
view (const std::basic_string<CharT,Traits,Allocator> &val):
view (std::data (val), std::data (val) + std::size (val))
{ ; }
//---------------------------------------------------------------------
// contiguous containers are often used with pointers to their contents
// for other operations so we directly construct them using pointers to
// their data for user convenience.
template <
typename ContainerT,
typename std::enable_if_t<is_contiguous_v<ContainerT>,ContainerT*> = nullptr
>
constexpr explicit
view (
ContainerT &klass
):
view (std::data (klass), std::data (klass) + std::size (klass))
template <typename ValueT, typename AllocatorT>
view (const std::vector<ValueT,AllocatorT> &rhs):
view (std::data (rhs), std::data (rhs) + std::size (rhs))
{ ; }
//---------------------------------------------------------------------
template <typename ValueT, typename AllocatorT>
view (std::vector<ValueT,AllocatorT> &rhs):
view (std::data (rhs), std::data (rhs) + std::size (rhs))
{ ; }
@ -280,6 +306,12 @@ namespace util {
view (const ValueT(&)[N]) -> view<const ValueT*,const ValueT*>;
//-------------------------------------------------------------------------
view (const char*) -> view<const char*>;
view (char*) -> view<char*>;
//-------------------------------------------------------------------------
template <
typename IteratorT,
@ -291,28 +323,19 @@ namespace util {
view (IteratorT, SizeT) -> view<IteratorT,IteratorT>;
//-------------------------------------------------------------------------
template <
typename ContainerT,
typename = std::enable_if_t<is_contiguous_v<ContainerT>, void>
>
view (ContainerT&) -> view<
typename ContainerT::value_type*,
typename ContainerT::value_type*
>;
template <typename CharT, typename Traits, typename Allocator>
view (std::basic_string<CharT,Traits,Allocator> &) -> view<typename Allocator::pointer>;
//-------------------------------------------------------------------------
template <
typename ContainerT,
typename = std::enable_if_t<!is_contiguous_v<ContainerT>, void>
>
view (ContainerT&) -> view<
decltype (std::begin (std::declval<ContainerT> ())),
decltype (std::end (std::declval<ContainerT> ()))
>;
template <typename CharT, typename Traits, typename Allocator>
view (const std::basic_string<CharT,Traits,Allocator> &) -> view<typename Allocator::const_pointer>;
template <typename ValueT, typename AllocatorT>
view (std::vector<ValueT,AllocatorT>&) -> view<typename AllocatorT::pointer>;
template <typename ValueT, typename AllocatorT>
view (const std::vector<ValueT,AllocatorT>&) -> view<typename AllocatorT::const_pointer>;
///////////////////////////////////////////////////////////////////////////
@ -478,9 +501,9 @@ namespace util {
///////////////////////////////////////////////////////////////////////////
template <typename IteratorT>
template <typename BeginT, typename EndT>
std::ostream&
operator<< (std::ostream &os, view<IteratorT> val)
operator<< (std::ostream &os, view<BeginT, EndT> val)
{
std::copy (
std::cbegin (val),