Logo ROOT   6.16/01
Reference Guide
span.hxx
Go to the documentation of this file.
1/// \file ROOT/rhysd_span.h
2/// \ingroup Base StdExt
3/// \author Axel Naumann <axel@cern.ch>
4/// \date 2015-09-06
5
6/*************************************************************************
7 * Copyright (C) 1995-2015, Rene Brun and Fons Rademakers. *
8 * All rights reserved. *
9 * *
10 * For the licensing terms see $ROOTSYS/LICENSE. *
11 * For the list of contributors see $ROOTSYS/README/CREDITS. *
12 *************************************************************************/
13
14#ifndef ROOT_RHYSD_SPAN_H
15#define ROOT_RHYSD_SPAN_H
16
17// Necessary to compile in c++11 mode
18#if __cplusplus >= 201402L
19#define R__CONSTEXPR_IF_CXX14 constexpr
20#else
21#define R__CONSTEXPR_IF_CXX14
22#endif
23
24// From https://github.com/rhysd/array_view/blob/master/include/array_view.hpp
25
26#include <cstddef>
27#include <iterator>
28#include <array>
29#include <vector>
30#include <stdexcept>
31#include <memory>
32#include <type_traits>
33#include <vector>
34#include <initializer_list>
35
36namespace ROOT {
37namespace Detail {
38using std::size_t;
39
40// detail meta functions {{{
41template<class Array>
43 static bool const value = false;
44};
45template<class T, size_t N>
46struct is_array_class<std::array<T, N>> {
47 static bool const value = true;
48};
49template<class T>
50struct is_array_class<std::vector<T>> {
51 static bool const value = true;
52};
53template<class T>
54struct is_array_class<std::initializer_list<T>> {
55 static bool const value = true;
56};
57// }}}
58
59// index sequences {{{
60template< size_t... Indices >
61struct indices{
62 static constexpr size_t value[sizeof...(Indices)] = {Indices...};
63};
64
65template<class IndicesType, size_t Next>
67
68template<size_t... Indices, size_t Next>
69struct make_indices_next<indices<Indices...>, Next> {
70 typedef indices<Indices..., (Indices + Next)...> type;
71};
72
73template<class IndicesType, size_t Next, size_t Tail>
75
76template<size_t... Indices, size_t Next, size_t Tail>
77struct make_indices_next2<indices<Indices...>, Next, Tail> {
78 typedef indices<Indices..., (Indices + Next)..., Tail> type;
79};
80
81template<size_t First, size_t Step, size_t N, class = void>
83
84template<size_t First, size_t Step, size_t N>
86 First,
87 Step,
88 N,
89 typename std::enable_if<(N == 0)>::type
90> {
91 typedef indices<> type;
92};
93
94template<size_t First, size_t Step, size_t N>
96 First,
97 Step,
98 N,
99 typename std::enable_if<(N == 1)>::type
100> {
102};
103
104template<size_t First, size_t Step, size_t N>
106 First,
107 Step,
108 N,
109 typename std::enable_if<(N > 1 && N % 2 == 0)>::type
110>
112 typename ROOT::Detail::make_indices_impl<First, Step, N / 2>::type,
113 First + N / 2 * Step
114 >
115{};
116
117template<size_t First, size_t Step, size_t N>
119 First,
120 Step,
121 N,
122 typename std::enable_if<(N > 1 && N % 2 == 1)>::type
123>
125 typename ROOT::Detail::make_indices_impl<First, Step, N / 2>::type,
126 First + N / 2 * Step,
127 First + (N - 1) * Step
128 >
129{};
130
131template<size_t First, size_t Last, size_t Step = 1>
134 First,
135 Step,
136 ((Last - First) + (Step - 1)) / Step
137 >
138{};
139
140template < size_t Start, size_t Last, size_t Step = 1 >
142// }}}
143} // namespace Detail
144}
145
146namespace std {
147
148inline namespace __ROOT {
149
150// span {{{
151
153static constexpr check_bound_t check_bound{};
154
155template<class T>
156class span {
157public:
158 /*
159 * types
160 */
161 typedef T value_type;
162 typedef value_type const* pointer;
163 typedef value_type const* const_pointer;
164 typedef value_type const& reference;
166 typedef value_type const* iterator;
168 typedef size_t size_type;
169 typedef ptrdiff_t difference_type;
170 typedef std::reverse_iterator<iterator> reverse_iterator;
171 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
172
173 /*
174 * ctors and assign operators
175 */
176 constexpr span() noexcept
177 : length_(0), data_(nullptr)
178 {}
179
180 constexpr span(span const&) noexcept = default;
181 constexpr span(span &&) noexcept = default;
182
183 // Note:
184 // This constructor can't be constexpr because & operator can't be constexpr.
185 template<size_type N>
186 /*implicit*/ span(std::array<T, N> const& a) noexcept
187 : length_(N), data_(N > 0 ? a.data() : nullptr)
188 {}
189
190 // Note:
191 // This constructor can't be constexpr because & operator can't be constexpr.
192 template<size_type N>
193 /*implicit*/ span(T const (& a)[N]) noexcept
194 : length_(N), data_(N > 0 ? std::addressof(a[0]) : nullptr)
195 {
196 static_assert(N > 0, "Zero-length array is not permitted in ISO C++.");
197 }
198
199 /*implicit*/ span(std::vector<T> const& v) noexcept
200 : length_(v.size()), data_(v.empty() ? nullptr : v.data())
201 {}
202
203 /*implicit*/ constexpr span(T const* a, size_type const n) noexcept
204 : length_(n), data_(a)
205 {}
206
207 template<
208 class InputIterator,
209 class = typename std::enable_if<
210 std::is_same<
211 T,
212 typename std::iterator_traits<InputIterator>::value_type
213 >::value
214 >::type
215 >
216 explicit span(InputIterator start, InputIterator last)
217 : length_(std::distance(start, last)), data_(start)
218 {}
219
220 span(std::initializer_list<T> const& l)
221 : length_(l.size()), data_(std::begin(l))
222 {}
223
224 span& operator=(span const&) noexcept = delete;
225 span& operator=(span &&) noexcept = delete;
226
227 /*
228 * iterator interfaces
229 */
230 constexpr const_iterator begin() const noexcept
231 {
232 return data_;
233 }
234 constexpr const_iterator end() const noexcept
235 {
236 return data_ + length_;
237 }
238 constexpr const_iterator cbegin() const noexcept
239 {
240 return begin();
241 }
242 constexpr const_iterator cend() const noexcept
243 {
244 return end();
245 }
247 {
248 return {end()};
249 }
251 {
252 return {begin()};
253 }
255 {
256 return rbegin();
257 }
259 {
260 return rend();
261 }
262
263 /*
264 * access
265 */
266 constexpr size_type size() const noexcept
267 {
268 return length_;
269 }
270 constexpr size_type length() const noexcept
271 {
272 return size();
273 }
274 constexpr size_type max_size() const noexcept
275 {
276 return size();
277 }
278 constexpr bool empty() const noexcept
279 {
280 return length_ == 0;
281 }
282 constexpr const_reference operator[](size_type const n) const noexcept
283 {
284 return *(data_ + n);
285 }
286 constexpr const_reference at(size_type const n) const
287 {
288 //Works only in C++14
289 //if (n >= length_) throw std::out_of_range("span::at()");
290 //return *(data_ + n);
291 return n >= length_ ? throw std::out_of_range("span::at()") : *(data_ + n);
292 }
293 constexpr const_pointer data() const noexcept
294 {
295 return data_;
296 }
297 constexpr const_reference front() const noexcept
298 {
299 return *data_;
300 }
301 constexpr const_reference back() const noexcept
302 {
303 return *(data_ + length_ - 1);
304 }
305
306 /*
307 * slices
308 */
309 // slice with indices {{{
310 // check bound {{{
311 constexpr span<T> slice(check_bound_t, size_type const pos, size_type const slicelen) const
312 {
313 //Works only in C++14
314 //if (pos >= length_ || pos + slicelen >= length_) {
315 // throw std::out_of_range("span::slice()");
316 //}
317 //return span<T>{begin() + pos, begin() + pos + slicelen};
318 return pos >= length_ || pos + slicelen >= length_ ? throw std::out_of_range("span::slice()") : span<T>{begin() + pos, begin() + pos + slicelen};
319 }
320 constexpr span<T> slice_before(check_bound_t, size_type const pos) const
321 {
322 //Works only in C++14
323 //if (pos >= length_) {
324 // throw std::out_of_range("span::slice()");
325 //}
326 //return span<T>{begin(), begin() + pos};
327 return pos >= length_ ? std::out_of_range("span::slice()") : span<T>{begin(), begin() + pos};
328 }
329 constexpr span<T> slice_after(check_bound_t, size_type const pos) const
330 {
331 //Works only in C++14
332 //if (pos >= length_) {
333 // throw std::out_of_range("span::slice()");
334 //}
335 //return span<T>{begin() + pos, end()};
336 return pos >= length_ ? std::out_of_range("span::slice()") : span<T>{begin() + pos, end()};
337 }
338 // }}}
339 // not check bound {{{
340 constexpr span<T> slice(size_type const pos, size_type const slicelen) const
341 {
342 return span<T>{begin() + pos, begin() + pos + slicelen};
343 }
344 constexpr span<T> slice_before(size_type const pos) const
345 {
346 return span<T>{begin(), begin() + pos};
347 }
348 constexpr span<T> slice_after(size_type const pos) const
349 {
350 return span<T>{begin() + pos, end()};
351 }
352 // }}}
353 // }}}
354 // slice with iterators {{{
355 // check bound {{{
356 constexpr span<T> slice(check_bound_t, iterator start, iterator last) const
357 {
358 //Works only in C++14
359 //if ( start >= end() ||
360 // last > end() ||
361 // start > last ||
362 // static_cast<size_t>(std::distance(start, last > end() ? end() : last)) > length_ - std::distance(begin(), start) ) {
363 // throw std::out_of_range("span::slice()");
364 //}
365 //return span<T>{start, last > end() ? end() : last};
366 return ( start >= end() ||
367 last > end() ||
368 start > last ||
369 static_cast<size_t>(std::distance(start, last > end() ? end() : last)) > length_ - std::distance(begin(), start) ) ? throw std::out_of_range("span::slice()") : span<T>{start, last > end() ? end() : last};
370 }
371 constexpr span<T> slice_before(check_bound_t, iterator const pos) const
372 {
373 //Works only in C++14
374 //if (pos < begin() || pos > end()) {
375 // throw std::out_of_range("span::slice()");
376 //}
377 //return span<T>{begin(), pos > end() ? end() : pos};
378 return pos < begin() || pos > end() ? throw std::out_of_range("span::slice()") : span<T>{begin(), pos > end() ? end() : pos};
379 }
380 constexpr span<T> slice_after(check_bound_t, iterator const pos) const
381 {
382 //Works only in C++14
383 // if (pos < begin() || pos > end()) {
384 // throw std::out_of_range("span::slice()");
385 //}
386 //return span<T>{pos < begin() ? begin() : pos, end()};
387 return pos < begin() || pos > end() ? throw std::out_of_range("span::slice()") : span<T>{pos < begin() ? begin() : pos, end()};
388 }
389 // }}}
390 // not check bound {{{
391 constexpr span<T> slice(iterator start, iterator last) const
392 {
393 return span<T>{start, last};
394 }
395 constexpr span<T> slice_before(iterator const pos) const
396 {
397 return span<T>{begin(), pos};
398 }
399 constexpr span<T> slice_after(iterator const pos) const
400 {
401 return span<T>{pos, end()};
402 }
403 // }}}
404 // }}}
405
406 /*
407 * others
408 */
409 template<class Allocator = std::allocator<T>>
410 auto to_vector(Allocator const& alloc = Allocator{}) const
411 -> std::vector<T, Allocator>
412 {
413 return {begin(), end(), alloc};
414 }
415
416 template<size_t N>
417 auto to_array() const
418 -> std::array<T, N>
419 {
421 }
422private:
423 template<size_t... I>
425 -> std::array<T, sizeof...(I)>
426 {
427 return {{(I < length_ ? *(data_ + I) : T{} )...}};
428 }
429
430private:
433};
434// }}}
435} // inline namespace __ROOT
436} // namespace std
437
438namespace ROOT {
439// compare operators {{{
440namespace Detail {
441
442template< class ArrayL, class ArrayR >
444bool operator_equal_impl(ArrayL const& lhs, size_t const lhs_size, ArrayR const& rhs, size_t const rhs_size)
445{
446 if (lhs_size != rhs_size) {
447 return false;
448 }
449
450 auto litr = std::begin(lhs);
451 auto ritr = std::begin(rhs);
452 for (; litr != std::end(lhs); ++litr, ++ritr) {
453 if (!(*litr == *ritr)) {
454 return false;
455 }
456 }
457
458 return true;
459}
460} // namespace Detail
461} // namespace ROOT
462
463namespace std {
464inline namespace __ROOT {
465
466template<class T1, class T2>
467inline constexpr
468bool operator==(span<T1> const& lhs, span<T2> const& rhs)
469{
470 return ROOT::Detail::operator_equal_impl(lhs, lhs.length(), rhs, rhs.length());
471}
472
473template<
474 class T,
475 class Array,
476 class = typename std::enable_if<
478 >::type
479>
480inline constexpr
481bool operator==(span<T> const& lhs, Array const& rhs)
482{
483 return ROOT::Detail::operator_equal_impl(lhs, lhs.length(), rhs, rhs.size());
484}
485
486template<class T1, class T2, size_t N>
487inline constexpr
488bool operator==(span<T1> const& lhs, T2 const (& rhs)[N])
489{
490 return ROOT::Detail::operator_equal_impl(lhs, lhs.length(), rhs, N);
491}
492
493template<
494 class T,
495 class Array,
496 class = typename std::enable_if<
497 is_array<Array>::value
498 >::type
499>
500inline constexpr
501bool operator!=(span<T> const& lhs, Array const& rhs)
502{
503 return !(lhs == rhs);
504}
505
506template<
507 class Array,
508 class T,
509 class = typename std::enable_if<
510 is_array<Array>::value
511 >::type
512>
513inline constexpr
514bool operator==(Array const& lhs, span<T> const& rhs)
515{
516 return rhs == lhs;
517}
518
519template<
520 class Array,
521 class T,
522 class = typename std::enable_if<
523 is_array<Array>::value,
524 Array
525 >::type
526>
527inline constexpr
528bool operator!=(Array const& lhs, span<T> const& rhs)
529{
530 return !(rhs == lhs);
531}
532// }}}
533
534// helpers to construct view {{{
535template<
536 class Array,
537 class = typename std::enable_if<
539 >::type
540>
541inline constexpr
542auto make_view(Array const& a)
543-> span<typename Array::value_type>
544{
545 return {a};
546}
547
548template< class T, size_t N>
549inline constexpr
550span<T> make_view(T const (&a)[N])
551{
552 return {a};
553}
554
555template<class T>
556inline constexpr
557span<T> make_view(T const* p, typename span<T>::size_type const n)
558{
559 return span<T>{p, n};
560}
561
562template<class InputIterator, class Result = span<typename std::iterator_traits<InputIterator>::value_type>>
563inline constexpr
564Result make_view(InputIterator begin, InputIterator end)
565{
566 return Result{begin, end};
567}
568
569template<class T>
570inline constexpr
571span<T> make_view(std::initializer_list<T> const& l)
572{
573 return {l};
574}
575// }}}
576
577} // inline namespace __ROOT
578} // namespace std
579
580
581
582
583
584#if 0
585// This stuff is too complex for our simple use case!
586
587#include <cstddef>
588#include <array>
589#include <type_traits>
590
591// See N3851
592
593namespace std {
594
595template<int Rank>
596class index;
597
598template<int Rank>
599class bounds {
600public:
601 static constexpr int rank = Rank;
602 using reference = ptrdiff_t &;
603 using const_reference = const ptrdiff_t &;
604 using size_type = size_t;
605 using value_type = ptrdiff_t;
606
607private:
608 std::array<value_type, Rank> m_B;
609
610public:
611 constexpr bounds() noexcept;
612
613 constexpr bounds(value_type b) noexcept: m_B{{b}} { };
614 //constexpr bounds(const initializer_list<value_type>&) noexcept;
615 //constexpr bounds(const bounds&) noexcept;
616 //bounds& operator=(const bounds&) noexcept;
617
618 reference operator[](size_type i) noexcept { return m_B[i]; }
619
620 constexpr const_reference operator[](
621 size_type i) const noexcept { return m_B[i]; };
622
623
624 bool operator==(const bounds &rhs) const noexcept;
625
626 bool operator!=(const bounds &rhs) const noexcept;
627
628 bounds operator+(const index<rank> &rhs) const noexcept;
629
630 bounds operator-(const index<rank> &rhs) const noexcept;
631
632 bounds &operator+=(const index<rank> &rhs) noexcept;
633
634 bounds &operator-=(const index<rank> &rhs) noexcept;
635
636 constexpr size_type size() const noexcept;
637
638 bool contains(const index<rank> &idx) const noexcept;
639 //bounds_iterator<rank> begin() const noexcept;
640 //bounds_iterator<rank> end() const noexcept;
641
642};
643
644//bounds operator+(const index<rank>& lhs, const bounds& rhs) noexcept;
645
646template<int Rank>
647class index {
648public:
649 static constexpr int rank = Rank;
650 using reference = ptrdiff_t &;
651 using const_reference = const ptrdiff_t &;
652 using size_type = size_t;
653 using value_type = ptrdiff_t;
654
655// For index<rank>:
656 constexpr index() noexcept;
657
658 constexpr index(value_type) noexcept;
659
660 constexpr index(const initializer_list<value_type> &) noexcept;
661
662 constexpr index(const index &) noexcept;
663
664 index &operator=(const index &) noexcept;
665
666 reference operator[](size_type component_idx) noexcept;
667
668 constexpr const_reference operator[](size_type component_idx) const noexcept;
669
670 bool operator==(const index &rhs) const noexcept;
671
672 bool operator!=(const index &rhs) const noexcept;
673
674 index operator+(const index &rhs) const noexcept;
675
676 index operator-(const index &rhs) const noexcept;
677
678 index &operator+=(const index &rhs) noexcept;
679
680 index &operator-=(const index &rhs) noexcept;
681
682 index &operator++() noexcept;
683
684 index operator++(int) noexcept;
685
686 index &operator--() noexcept;
687
688 index operator--(int) noexcept;
689
690 index operator+() const noexcept;
691
692 index operator-() const noexcept;
693};
694
695/// Mock-up of future atd::(experimental::)span.
696/// Supports only what we need for THist, e.g. Rank := 1.
697template<typename ValueType, int Rank = 1>
698class span {
699public:
700 static constexpr int rank = Rank;
701 using index_type = index<rank>;
702 using bounds_type = bounds<rank>;
703 using size_type = typename bounds_type::size_type;
704 using value_type = ValueType;
705 using pointer = typename std::add_pointer_t<value_type>;
706 using reference = typename std::add_lvalue_reference_t<value_type>;
707
708 constexpr span() noexcept;
709
710 constexpr explicit span(std::vector<ValueType> &cont) noexcept;
711
712 template<typename ArrayType>
713 constexpr explicit span(ArrayType &data) noexcept;
714
715 template<typename ViewValueType>
716 constexpr span(const span<ViewValueType, rank> &rhs) noexcept;
717
718 template<typename Container>
719 constexpr span(bounds_type bounds, Container &cont) noexcept;
720
721 constexpr span(bounds_type bounds, pointer data) noexcept;
722
723 template<typename ViewValueType>
724 span &operator=(const span<ViewValueType, rank> &rhs) noexcept;
725
726 constexpr bounds_type bounds() const noexcept;
727 constexpr size_type size() const noexcept;
728 constexpr index_type stride() const noexcept;
729
730 constexpr pointer data() const noexcept;
731 constexpr reference operator[](const index_type& idx) const noexcept;
732};
733
734}
735#endif // too complex!
736#endif
SVector< double, 2 > v
Definition: Dict.h:5
#define b(i)
Definition: RSha256.hxx:100
#define N
int type
Definition: TGX11.cxx:120
TString operator+(const TString &s1, const TString &s2)
Use the special concatenation constructor.
Definition: TString.cxx:1449
std::string & operator+=(std::string &left, const TString &right)
Definition: TString.h:473
TTime operator-(const TTime &t1, const TTime &t2)
Definition: TTime.h:83
const_pointer const data_
Definition: span.hxx:432
span(InputIterator start, InputIterator last)
Definition: span.hxx:216
constexpr span< T > slice(size_type const pos, size_type const slicelen) const
Definition: span.hxx:340
constexpr span< T > slice_before(check_bound_t, size_type const pos) const
Definition: span.hxx:320
constexpr span< T > slice_after(check_bound_t, size_type const pos) const
Definition: span.hxx:329
size_t size_type
Definition: span.hxx:168
auto to_vector(Allocator const &alloc=Allocator{}) const -> std::vector< T, Allocator >
Definition: span.hxx:410
constexpr span< T > slice_after(iterator const pos) const
Definition: span.hxx:399
const_reverse_iterator crend() const
Definition: span.hxx:258
span & operator=(span const &) noexcept=delete
constexpr const_reference back() const noexcept
Definition: span.hxx:301
constexpr span< T > slice_before(check_bound_t, iterator const pos) const
Definition: span.hxx:371
constexpr const_iterator cbegin() const noexcept
Definition: span.hxx:238
constexpr span< T > slice(iterator start, iterator last) const
Definition: span.hxx:391
constexpr const_iterator end() const noexcept
Definition: span.hxx:234
span(std::vector< T > const &v) noexcept
Definition: span.hxx:199
constexpr const_iterator cend() const noexcept
Definition: span.hxx:242
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: span.hxx:171
size_type const length_
Definition: span.hxx:431
const_reverse_iterator rbegin() const
Definition: span.hxx:246
value_type const & reference
Definition: span.hxx:164
const_reverse_iterator crbegin() const
Definition: span.hxx:254
span(std::initializer_list< T > const &l)
Definition: span.hxx:220
value_type const * iterator
Definition: span.hxx:166
constexpr span< T > slice(check_bound_t, iterator start, iterator last) const
Definition: span.hxx:356
constexpr span(span &&) noexcept=default
constexpr span< T > slice(check_bound_t, size_type const pos, size_type const slicelen) const
Definition: span.hxx:311
constexpr span< T > slice_before(size_type const pos) const
Definition: span.hxx:344
std::reverse_iterator< iterator > reverse_iterator
Definition: span.hxx:170
constexpr bool empty() const noexcept
Definition: span.hxx:278
value_type const * const_iterator
Definition: span.hxx:167
constexpr const_reference at(size_type const n) const
Definition: span.hxx:286
value_type const & const_reference
Definition: span.hxx:165
constexpr const_reference operator[](size_type const n) const noexcept
Definition: span.hxx:282
auto to_array_impl(ROOT::Detail::indices< I... >) const -> std::array< T, sizeof...(I)>
Definition: span.hxx:424
constexpr const_reference front() const noexcept
Definition: span.hxx:297
constexpr size_type max_size() const noexcept
Definition: span.hxx:274
constexpr size_type length() const noexcept
Definition: span.hxx:270
span(T const (&a)[N]) noexcept
Definition: span.hxx:193
span & operator=(span &&) noexcept=delete
value_type const * const_pointer
Definition: span.hxx:163
const_reverse_iterator rend() const
Definition: span.hxx:250
constexpr size_type size() const noexcept
Definition: span.hxx:266
constexpr span(T const *a, size_type const n) noexcept
Definition: span.hxx:203
value_type const * pointer
Definition: span.hxx:162
constexpr span< T > slice_after(size_type const pos) const
Definition: span.hxx:348
constexpr span() noexcept
Definition: span.hxx:176
constexpr span(span const &) noexcept=default
constexpr span< T > slice_after(check_bound_t, iterator const pos) const
Definition: span.hxx:380
ptrdiff_t difference_type
Definition: span.hxx:169
constexpr const_pointer data() const noexcept
Definition: span.hxx:293
auto to_array() const -> std::array< T, N >
Definition: span.hxx:417
constexpr const_iterator begin() const noexcept
Definition: span.hxx:230
constexpr span< T > slice_before(iterator const pos) const
Definition: span.hxx:395
const Int_t n
Definition: legend1.C:16
#define T2
Definition: md5.inl:146
#define I(x, y, z)
R__CONSTEXPR_IF_CXX14 bool operator_equal_impl(ArrayL const &lhs, size_t const lhs_size, ArrayR const &rhs, size_t const rhs_size)
Definition: span.hxx:444
typename make_indices_< Start, Last, Step >::type make_indices
Definition: span.hxx:141
double T(double x)
Definition: ChebyshevPol.h:34
void Step(const gsl_rng *r, void *xp, double step_size)
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
const char * Array
constexpr bool operator!=(span< T > const &lhs, Array const &rhs)
Definition: span.hxx:501
constexpr auto make_view(Array const &a) -> span< typename Array::value_type >
Definition: span.hxx:542
static constexpr check_bound_t check_bound
Definition: span.hxx:153
constexpr bool operator==(span< T1 > const &lhs, span< T2 > const &rhs)
Definition: span.hxx:468
STL namespace.
#define R__CONSTEXPR_IF_CXX14
Definition: span.hxx:21
static constexpr size_t value[sizeof...(Indices)]
Definition: span.hxx:62
static bool const value
Definition: span.hxx:43
auto * l
Definition: textangle.C:4
auto * a
Definition: textangle.C:12