cppx-core
Span_.hpp
Go to the documentation of this file.
1 #pragma once // Source encoding: UTF-8 with BOM (π is a lowercase Greek "pi").
2 //
3 // Mainly for use with range based `for` loops.
4 
5 #include <cppx-core/collections/is_empty.hpp> // cppx::is_empty
6 #include <cppx-core/language/syntax/macro-use.hpp> // CPPX_USE_STD
8 #include <cppx-core/language/types/Truth.hpp> // cppx::Truth
9 
10 #include <iterator> // std::(begin, distance, end, prev, next, make_reverse_iterator, reverse_iterator )
11 #include <queue> // std::queue
12 #include <stack> // std::stack
13 #include <utility> // std::(declval, move)
14 
15 namespace cppx
16 {
18  begin, declval, distance, end, make_reverse_iterator, move, next, prev,
19  queue, reverse_iterator, stack
20  );
21 
22  template< class Collection >
23  inline auto it_begin_of(Collection&& c)
24  {
25  using std::begin;
26  return begin( c );
27  }
28 
29  template< class Collection >
30  inline auto it_end_of(Collection&& c)
31  {
32  using std::end;
33  return end( c );
34  }
35 
36  template< class Iterator >
37  class Span_
38  {
39  Iterator m_first;
40  Iterator m_beyond;
41 
42  public:
43  auto first() const -> Iterator { return m_first; }
44  auto beyond() const -> Iterator { return m_beyond; }
45  auto& front() const { return *m_first; }
46  auto is_empty() const -> Truth { return (m_first == m_beyond); }
47 
48  // Standard library & core language naming convention adapters.
49  auto begin() const -> Iterator { return m_first; }
50  auto end() const -> Iterator { return m_beyond; }
51  auto empty() const -> Truth { return (m_first == m_beyond); }
52 
53  Span_( const Iterator first, const Iterator beyond ):
54  m_first( first ),
55  m_beyond( beyond )
56  {}
57 
58  template< class Collection >
59  Span_( Collection&& c ):
60  m_first( it_begin_of( c ) ),
61  m_beyond( it_end_of( c ) )
62  {}
63  };
64 
65  template< class Item >
67 
68  template< class Iterator >
69  inline auto n_items_of( const Span_<Iterator>& range )
70  -> Size
71  { return distance( range.begin(), range.end() ); }
72 
73  template< class Iterator >
74  inline auto span_of( const Iterator first, const Iterator beyond )
76  { return Span_<Iterator>( first, beyond ); }
77 
78  template< class Container >
79  inline auto all_of( Container&& c )
80  -> Span_<decltype( begin( c ) )>
81  { return span_of( begin( c ), end( c ) ); }
82 
83  template< class Item, class Container >
84  auto all_of( const queue<Item, Container>& q )
86  {
87  struct Accessible: queue<Item, Container>
88  {
89  static auto container_of( const queue<Item, Container>& q )
90  -> const Container&
91  { return q.*&Accessible::c; }
92  };
93 
94  return all_of( Accessible::container_of( q ) );
95  }
96 
97  template< class Item, class Container >
98  auto all_of( const stack<Item, Container>& st )
100  {
101  struct Accessible: stack<Item, Container>
102  {
103  static auto container_of( const stack<Item, Container>& st )
104  -> const Container&
105  { return st.*&Accessible::c; }
106  };
107 
108  return all_of( Accessible::container_of( st ) );
109  }
110 
111  template< class Container >
112  inline auto all_but_first_of( Container&& c )
113  -> Span_<decltype( begin( c ) )>
114  {
115  const auto all = all_of( c );
116  return span_of( next( all.first() ), all.beyond() );
117  }
118 
119  template< class Container >
120  inline auto all_but_first_n_of( Container&& c, const Size n )
121  -> Span_<decltype( begin( c ) )>
122  {
123  const auto all = all_of( c );
124  return span_of( next( all.first(), n ), all.beyond() );
125  }
126 
127  template< class Container >
128  inline auto all_but_last_of( Container&& c )
129  -> Span_<decltype( begin( c ) )>
130  {
131  const auto all = all_of( c );
132  return span_of( all.first(), prev( all.beyond() ) );
133  }
134 
135  template<
136  class Char, Size n
137  //,class = Enable_if_<is_a_char_type_<Char>>
138  >
139  inline auto text_span_of_literal( const Raw_array_of_<n, const Char>& string_literal )
141  { return all_but_last_of( string_literal ); }
142 
143  template< class Container >
144  inline auto all_but_last_n_of( Container&& c, const Size n )
145  -> Span_<decltype( begin( c ) )>
146  {
147  const auto all = all_of( c );
148  return span_of( all.first(), prev( all.beyond(), n ) );
149  }
150 
151  template< class Container >
152  inline auto reversed( Container&& c )
153  -> Span_<reverse_iterator<decltype( begin( c ) )>>
154  {
155  const auto all = all_of( c );
156  return span_of(
157  make_reverse_iterator( all.beyond() ),
158  make_reverse_iterator( all.first() )
159  );
160  }
161 
162 } // namespace cppx
auto first() const -> Iterator
Definition: Span_.hpp:43
constexpr auto n_items_of(const Collection &c) noexcept -> Size
auto prev(P_< const char > p) -> P_< const char >
A drop-in replacement for bool without implicit conversion from/to types other than bool.
Definition: Truth.hpp:34
auto all_but_first_n_of(Container &&c, const Size n) -> Span_< decltype(begin(c))>
Definition: Span_.hpp:120
auto all_of(Container &&c) -> Span_< decltype(begin(c))>
Definition: Span_.hpp:79
auto begin() const -> Iterator
Definition: Span_.hpp:49
auto all_but_first_of(Container &&c) -> Span_< decltype(begin(c))>
Definition: Span_.hpp:112
auto all_but_last_n_of(Container &&c, const Size n) -> Span_< decltype(begin(c))>
Definition: Span_.hpp:144
auto it_begin_of(Collection &&c)
Definition: Span_.hpp:23
auto it_end_of(Collection &&c)
Definition: Span_.hpp:30
Span_(Collection &&c)
Definition: Span_.hpp:59
auto end() const -> Iterator
Definition: Span_.hpp:50
Span_(const Iterator first, const Iterator beyond)
Definition: Span_.hpp:53
Truth is a drop-in replacement for bool without implicit conversion from/to types other than bool.
auto text_span_of_literal(const Raw_array_of_< n, const Char > &string_literal) -> Span_< P_< const Char >>
Definition: Span_.hpp:139
CPPX_USE_STD(basic_string, basic_string_view, bitset, char_traits, size)
auto span_of(const Iterator first, const Iterator beyond) -> Span_< Iterator >
Definition: Span_.hpp:74
auto is_empty() const -> Truth
Definition: Span_.hpp:46
auto next(P_< const char > p) -> P_< const char >
Signed_< size_t > Size
A Signed_ equivalent of size_t.
auto beyond() const -> Iterator
Definition: Span_.hpp:44
Item[n] Raw_array_of_
Creates a raw array type of a specified size.
void reversed(const Range_< Integer > &)=delete
auto & front() const
Definition: Span_.hpp:45
Macros for generating more concise and clear using statements, primarily $use_cppx and $use_std,...
auto empty() const -> Truth
Definition: Span_.hpp:51
Signed Size and Index, plus unsigned equivalents Unsigned_size and Unsigned_index.
auto all_but_last_of(Container &&c) -> Span_< decltype(begin(c))>
Definition: Span_.hpp:128