Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
span.hxx
Go to the documentation of this file.
1/// \file ROOT/span.hxx
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#if __cplusplus >= 202002
18# if __has_include(<span>)
19# include <span>
20# endif
21#endif
22
23#if !defined(__cpp_lib_span)
24
25// Necessary to compile in c++11 mode
26#if __cplusplus >= 201402L
27#define R__CONSTEXPR_IF_CXX14 constexpr
28#else
29#define R__CONSTEXPR_IF_CXX14
30#endif
31
32// From https://github.com/rhysd/array_view/blob/master/include/array_view.hpp
33
34#include <cstddef>
35#include <iterator>
36#include <array>
37#include <vector>
38#include <stdexcept>
39#include <memory>
40#include <type_traits>
41#include <initializer_list>
42
43namespace ROOT {
44namespace Detail {
45using std::size_t;
46
47// detail meta functions {{{
48template<class Array>
50 static bool const value = false;
51};
52template<class T, size_t N>
53struct is_array_class<std::array<T, N>> {
54 static bool const value = true;
55};
56template<class T>
57struct is_array_class<std::vector<T>> {
58 static bool const value = true;
59};
60template<class T>
61struct is_array_class<std::initializer_list<T>> {
62 static bool const value = true;
63};
64// }}}
65
66// index sequences {{{
67template< size_t... Indices >
68struct indices{
69 static constexpr size_t value[sizeof...(Indices)] = {Indices...};
70};
71
72template<class IndicesType, size_t Next>
74
75template<size_t... Indices, size_t Next>
77 typedef indices<Indices..., (Indices + Next)...> type;
78};
79
80template<class IndicesType, size_t Next, size_t Tail>
82
83template<size_t... Indices, size_t Next, size_t Tail>
85 typedef indices<Indices..., (Indices + Next)..., Tail> type;
86};
87
88template<size_t First, size_t Step, size_t N, class = void>
90
91template<size_t First, size_t Step, size_t N>
93 First,
94 Step,
95 N,
96 typename std::enable_if<(N == 0)>::type
97> {
98 typedef indices<> type;
99};
100
101template<size_t First, size_t Step, size_t N>
102struct make_indices_impl<
103 First,
104 Step,
105 N,
106 typename std::enable_if<(N == 1)>::type
107> {
108 typedef indices<First> type;
109};
110
111template<size_t First, size_t Step, size_t N>
112struct make_indices_impl<
113 First,
114 Step,
115 N,
116 typename std::enable_if<(N > 1 && N % 2 == 0)>::type
117>
119 typename ROOT::Detail::make_indices_impl<First, Step, N / 2>::type,
120 First + N / 2 * Step
121 >
122{};
123
124template<size_t First, size_t Step, size_t N>
125struct make_indices_impl<
126 First,
127 Step,
128 N,
129 typename std::enable_if<(N > 1 && N % 2 == 1)>::type
130>
132 typename ROOT::Detail::make_indices_impl<First, Step, N / 2>::type,
133 First + N / 2 * Step,
134 First + (N - 1) * Step
135 >
136{};
137
138template<size_t First, size_t Last, size_t Step = 1>
141 First,
142 Step,
143 ((Last - First) + (Step - 1)) / Step
144 >
145{};
146
147template < size_t Start, size_t Last, size_t Step = 1 >
149// }}}
150} // namespace Detail
151}
152
153namespace std {
154
155inline namespace __ROOT {
156
157// span {{{
158
159struct check_bound_t {};
160static constexpr check_bound_t check_bound{};
161
162template<class T>
163class span {
164public:
165 /*
166 * types
167 */
168 typedef T element_type;
169 typedef std::remove_cv<T> value_type;
170 typedef element_type * pointer;
171 typedef element_type const* const_pointer;
172 typedef element_type & reference;
173 typedef element_type const& const_reference;
174 typedef element_type * iterator;
175 typedef element_type const* const_iterator;
176 typedef ptrdiff_t difference_type;
177 typedef std::size_t size_type;
178 typedef std::reverse_iterator<iterator> reverse_iterator;
179 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
180
181 /*
182 * ctors and assign operators
183 */
184 constexpr span() noexcept
185 : length_(0), data_(nullptr)
186 {}
187
188 constexpr span(span const&) noexcept = default;
189 constexpr span(span &&) noexcept = default;
190
191 // Note:
192 // This constructor can't be constexpr because & operator can't be constexpr.
193 template<size_type N>
194 /*implicit*/ span(std::array<T, N> & a) noexcept
195 : length_(N), data_(N > 0 ? a.data() : nullptr)
196 {}
197
198 // Note:
199 // This constructor can't be constexpr because & operator can't be constexpr.
200 template<size_type N>
201 /*implicit*/ span(T(& a)[N]) noexcept
202 : length_(N), data_(N > 0 ? std::addressof(a[0]) : nullptr)
203 {
204 static_assert(N > 0, "Zero-length array is not permitted in ISO C++.");
205 }
206
207 // Note:
208 // This constructor needs to be disabled if T is not a const type, because we
209 // don't want to create span<T> from vector<T> const&.
210 // The explicit disabling via SFINAE is necessary to this overload is not
211 // accidentally taken by cppyy, resulting in the failure of constructor
212 // wrapper code compilation.
214 /*implicit*/ span(std::vector<typename std::remove_cv<T>::type> const& v) noexcept
215 : length_(v.size()), data_(v.empty() ? nullptr : v.data())
216 {}
217
218 /*implicit*/ span(std::vector<typename std::remove_cv<T>::type> & v) noexcept
219 : length_(v.size()), data_(v.empty() ? nullptr : v.data())
220 {}
221
222 /*implicit*/ constexpr span(pointer a, size_type const n) noexcept
223 : length_(n), data_(a)
224 {}
225
226 template<
227 class InputIterator,
228 class = typename std::enable_if<
229 std::is_same<
230 typename std::remove_cv<T>::type,
231 typename std::iterator_traits<InputIterator>::value_type
232 >::value
233 >::type
234 >
235 span(InputIterator start, InputIterator last)
236 : length_(std::distance(start, last)), data_(&*start)
237 {}
238
239 span(std::initializer_list<T> const& l)
240 : length_(l.size()), data_(std::begin(l))
241 {}
242
243 span& operator=(span const&) noexcept = default;
244 span& operator=(span &&) noexcept = delete;
245
246 /*
247 * iterator interfaces
248 */
249 constexpr iterator begin() const noexcept
250 {
251 return data_;
252 }
253 constexpr iterator end() const noexcept
254 {
255 return data_ + length_;
256 }
257 constexpr const_iterator cbegin() const noexcept
258 {
259 return begin();
260 }
261 constexpr const_iterator cend() const noexcept
262 {
263 return end();
264 }
265 reverse_iterator rbegin() const
266 {
267 return {end()};
268 }
269 reverse_iterator rend() const
270 {
271 return {begin()};
272 }
273 const_reverse_iterator crbegin() const
274 {
275 return rbegin();
276 }
277 const_reverse_iterator crend() const
278 {
279 return rend();
280 }
281
282 /*
283 * access
284 */
285 constexpr size_type size() const noexcept
286 {
287 return length_;
288 }
289 constexpr size_type length() const noexcept
290 {
291 return size();
292 }
293 constexpr size_type max_size() const noexcept
294 {
295 return size();
296 }
297 constexpr bool empty() const noexcept
298 {
299 return length_ == 0;
300 }
301 constexpr reference operator[](size_type const n) const noexcept
302 {
303 return *(data_ + n);
304 }
305 constexpr reference at(size_type const n) const
306 {
307 //Works only in C++14
308 //if (n >= length_) throw std::out_of_range("span::at()");
309 //return *(data_ + n);
310 return n >= length_ ? throw std::out_of_range("span::at()") : *(data_ + n);
311 }
312 constexpr pointer data() const noexcept
313 {
314 return data_;
315 }
316 constexpr const_reference front() const noexcept
317 {
318 return *data_;
319 }
320 constexpr const_reference back() const noexcept
321 {
322 return *(data_ + length_ - 1);
323 }
324
325 /*
326 * slices
327 */
328 // slice with indices {{{
329 // check bound {{{
330 constexpr span<T> slice(check_bound_t, size_type const pos, size_type const slicelen) const
331 {
332 //Works only in C++14
333 //if (pos >= length_ || pos + slicelen >= length_) {
334 // throw std::out_of_range("span::slice()");
335 //}
336 //return span<T>{begin() + pos, begin() + pos + slicelen};
337 return pos >= length_ || pos + slicelen >= length_ ? throw std::out_of_range("span::slice()") : span<T>{begin() + pos, begin() + pos + slicelen};
338 }
339 constexpr span<T> slice_before(check_bound_t, size_type const pos) const
340 {
341 //Works only in C++14
342 //if (pos >= length_) {
343 // throw std::out_of_range("span::slice()");
344 //}
345 //return span<T>{begin(), begin() + pos};
346 return pos >= length_ ? std::out_of_range("span::slice()") : span<T>{begin(), begin() + pos};
347 }
348 constexpr span<T> slice_after(check_bound_t, size_type const pos) const
349 {
350 //Works only in C++14
351 //if (pos >= length_) {
352 // throw std::out_of_range("span::slice()");
353 //}
354 //return span<T>{begin() + pos, end()};
355 return pos >= length_ ? std::out_of_range("span::slice()") : span<T>{begin() + pos, end()};
356 }
357 // }}}
358 // not check bound {{{
359 constexpr span<T> slice(size_type const pos, size_type const slicelen) const
360 {
361 return span<T>{begin() + pos, begin() + pos + slicelen};
362 }
363 constexpr span<T> slice_before(size_type const pos) const
364 {
365 return span<T>{begin(), begin() + pos};
366 }
367 constexpr span<T> slice_after(size_type const pos) const
368 {
369 return span<T>{begin() + pos, end()};
370 }
371 // }}}
372 // }}}
373 // slice with iterators {{{
374 // check bound {{{
375 constexpr span<T> slice(check_bound_t, iterator start, iterator last) const
376 {
377 //Works only in C++14
378 //if ( start >= end() ||
379 // last > end() ||
380 // start > last ||
381 // static_cast<size_t>(std::distance(start, last > end() ? end() : last)) > length_ - std::distance(begin(), start) ) {
382 // throw std::out_of_range("span::slice()");
383 //}
384 //return span<T>{start, last > end() ? end() : last};
385 return ( start >= end() ||
386 last > end() ||
387 start > last ||
388 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};
389 }
390 constexpr span<T> slice_before(check_bound_t, iterator const pos) const
391 {
392 //Works only in C++14
393 //if (pos < begin() || pos > end()) {
394 // throw std::out_of_range("span::slice()");
395 //}
396 //return span<T>{begin(), pos > end() ? end() : pos};
397 return pos < begin() || pos > end() ? throw std::out_of_range("span::slice()") : span<T>{begin(), pos > end() ? end() : pos};
398 }
399 constexpr span<T> slice_after(check_bound_t, iterator const pos) const
400 {
401 //Works only in C++14
402 // if (pos < begin() || pos > end()) {
403 // throw std::out_of_range("span::slice()");
404 //}
405 //return span<T>{pos < begin() ? begin() : pos, end()};
406 return pos < begin() || pos > end() ? throw std::out_of_range("span::slice()") : span<T>{pos < begin() ? begin() : pos, end()};
407 }
408 // }}}
409 // not check bound {{{
410 constexpr span<T> slice(iterator start, iterator last) const
411 {
412 return span<T>{start, last};
413 }
414 constexpr span<T> slice_before(iterator const pos) const
415 {
416 return span<T>{begin(), pos};
417 }
418 constexpr span<T> slice_after(iterator const pos) const
419 {
420 return span<T>{pos, end()};
421 }
422 // }}}
423 // }}}
424
425 /*
426 * others
427 */
429 auto to_vector(Allocator const& alloc = Allocator{}) const
430 -> std::vector<typename std::remove_cv<T>::type, Allocator>
431 {
432 return {begin(), end(), alloc};
433 }
434
435 template<size_t N>
436 auto to_array() const
437 -> std::array<T, N>
438 {
439 return to_array_impl(ROOT::Detail::make_indices<0, N>{});
440 }
441private:
442 template<size_t... I>
443 auto to_array_impl(ROOT::Detail::indices<I...>) const
444 -> std::array<T, sizeof...(I)>
445 {
446 return {{(I < length_ ? *(data_ + I) : T{} )...}};
447 }
448
449private:
450 size_type length_;
451 pointer data_;
452};
453// }}}
454} // inline namespace __ROOT
455} // namespace std
456
457namespace ROOT {
458// compare operators {{{
459namespace Detail {
460
461template< class ArrayL, class ArrayR >
463bool operator_equal_impl(ArrayL const& lhs, size_t const lhs_size, ArrayR const& rhs, size_t const rhs_size)
464{
465 if (lhs_size != rhs_size) {
466 return false;
467 }
468
469 auto litr = std::begin(lhs);
470 auto ritr = std::begin(rhs);
471 for (; litr != std::end(lhs); ++litr, ++ritr) {
472 if (!(*litr == *ritr)) {
473 return false;
474 }
475 }
476
477 return true;
478}
479} // namespace Detail
480} // namespace ROOT
481
482namespace std {
483inline namespace __ROOT {
484
485template<class T1, class T2>
486inline constexpr
487bool operator==(span<T1> const& lhs, span<T2> const& rhs)
488{
489 return ROOT::Detail::operator_equal_impl(lhs, lhs.length(), rhs, rhs.length());
490}
491
492template<
493 class T,
494 class Array,
495 class = typename std::enable_if<
497 >::type
498>
499inline constexpr
500bool operator==(span<T> const& lhs, Array const& rhs)
501{
502 return ROOT::Detail::operator_equal_impl(lhs, lhs.length(), rhs, rhs.size());
503}
504
505template<class T1, class T2, size_t N>
506inline constexpr
507bool operator==(span<T1> const& lhs, T2 const (& rhs)[N])
508{
509 return ROOT::Detail::operator_equal_impl(lhs, lhs.length(), rhs, N);
510}
511
512template<
513 class T,
514 class Array,
515 class = typename std::enable_if<
517 >::type
518>
519inline constexpr
520bool operator!=(span<T> const& lhs, Array const& rhs)
521{
522 return !(lhs == rhs);
523}
524
525template<
526 class Array,
527 class T,
528 class = typename std::enable_if<
530 >::type
531>
532inline constexpr
533bool operator==(Array const& lhs, span<T> const& rhs)
534{
535 return rhs == lhs;
536}
537
538template<
539 class Array,
540 class T,
541 class = typename std::enable_if<
543 Array
544 >::type
545>
546inline constexpr
547bool operator!=(Array const& lhs, span<T> const& rhs)
548{
549 return !(rhs == lhs);
550}
551// }}}
552
553// helpers to construct view {{{
554template<
555 class Array,
556 class = typename std::enable_if<
558 >::type
559>
560inline constexpr
561auto make_view(Array const& a)
563{
564 return {a};
565}
566
567template< class T, size_t N>
568inline constexpr
569span<T> make_view(T const (&a)[N])
570{
571 return {a};
572}
573
574template<class T>
575inline constexpr
576span<T> make_view(T const* p, typename span<T>::size_type const n)
577{
578 return span<T>{p, n};
579}
580
582inline constexpr
583Result make_view(InputIterator begin, InputIterator end)
584{
585 return Result{begin, end};
586}
587
588template<class T>
589inline constexpr
590span<T> make_view(std::initializer_list<T> const& l)
591{
592 return {l};
593}
594// }}}
595
596} // inline namespace __ROOT
597} // namespace std
598
599
600
601
602
603#if 0
604// This stuff is too complex for our simple use case!
605
606#include <cstddef>
607#include <array>
608#include <type_traits>
609
610// See N3851
611
612namespace std {
613
614template<int Rank>
615class index;
616
617template<int Rank>
618class bounds {
619public:
620 static constexpr int rank = Rank;
621 using reference = ptrdiff_t &;
622 using const_reference = const ptrdiff_t &;
623 using size_type = size_t;
624 using value_type = ptrdiff_t;
625
626private:
627 std::array<value_type, Rank> m_B;
628
629public:
630 constexpr bounds() noexcept;
631
632 constexpr bounds(value_type b) noexcept: m_B{{b}} { };
633 //constexpr bounds(const initializer_list<value_type>&) noexcept;
634 //constexpr bounds(const bounds&) noexcept;
635 //bounds& operator=(const bounds&) noexcept;
636
637 reference operator[](size_type i) noexcept { return m_B[i]; }
638
639 constexpr const_reference operator[](
640 size_type i) const noexcept { return m_B[i]; };
641
642
643 bool operator==(const bounds &rhs) const noexcept;
644
645 bool operator!=(const bounds &rhs) const noexcept;
646
647 bounds operator+(const index<rank> &rhs) const noexcept;
648
649 bounds operator-(const index<rank> &rhs) const noexcept;
650
651 bounds &operator+=(const index<rank> &rhs) noexcept;
652
653 bounds &operator-=(const index<rank> &rhs) noexcept;
654
655 constexpr size_type size() const noexcept;
656
657 bool contains(const index<rank> &idx) const noexcept;
658 //bounds_iterator<rank> begin() const noexcept;
659 //bounds_iterator<rank> end() const noexcept;
660
661};
662
663//bounds operator+(const index<rank>& lhs, const bounds& rhs) noexcept;
664
665template<int Rank>
666class index {
667public:
668 static constexpr int rank = Rank;
669 using reference = ptrdiff_t &;
670 using const_reference = const ptrdiff_t &;
671 using size_type = size_t;
672 using value_type = ptrdiff_t;
673
674// For index<rank>:
675 constexpr index() noexcept;
676
677 constexpr index(value_type) noexcept;
678
680
682
684
685 reference operator[](size_type component_idx) noexcept;
686
687 constexpr const_reference operator[](size_type component_idx) const noexcept;
688
690
692
694
696
698
700
702
703 index operator++(int) noexcept;
704
706
707 index operator--(int) noexcept;
708
710
712};
713
714/// Mock-up of future atd::(experimental::)span.
715/// Supports only what we need for THist, e.g. Rank := 1.
716template<typename ValueType, int Rank = 1>
717class span {
718public:
719 static constexpr int rank = Rank;
720 using size_type = index<rank>;
722 using size_type = typename bounds_type::size_type;
723 using value_type = ValueType;
724 using pointer = typename std::add_pointer_t<value_type>;
725 using reference = typename std::add_lvalue_reference_t<value_type>;
726
727 constexpr span() noexcept;
728
729 constexpr explicit span(std::vector<ValueType> &cont) noexcept;
730
733
736
739
740 constexpr span(bounds_type bounds, pointer data) noexcept;
741
744
746 constexpr size_type size() const noexcept;
747 constexpr size_type stride() const noexcept;
748
749 constexpr pointer data() const noexcept;
750 constexpr reference operator[](const size_type& idx) const noexcept;
751};
752
753}
754#endif // too complex!
755#endif // !defined(__cpp_lib_span)
756#endif
#define b(i)
Definition RSha256.hxx:100
#define a(i)
Definition RSha256.hxx:99
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Bool_t operator!=(const TDatime &d1, const TDatime &d2)
Definition TDatime.h:104
Bool_t operator==(const TDatime &d1, const TDatime &d2)
Definition TDatime.h:102
#define N
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Binding & operator=(OUT(*fun)(void))
TString operator+(const TString &s1, const TString &s2)
Use the special concatenation constructor.
Definition TString.cxx:1548
std::string & operator+=(std::string &left, const TString &right)
Definition TString.h:494
TTime operator-(const TTime &t1, const TTime &t2)
Definition TTime.h:83
RVec< T0 > & operator-=(RVec< T0 > &v, const T1 &y)
Definition RVec.hxx:1704
const Int_t n
Definition legend1.C:16
#define T2
Definition md5.inl:147
#define I(x, y, z)
typename make_indices_< Start, Last, Step >::type make_indices
Definition span.hxx:148
bool operator_equal_impl(ArrayL const &lhs, size_t const lhs_size, ArrayR const &rhs, size_t const rhs_size)
Definition span.hxx:463
Namespace for new ROOT classes and functions.
const char * Array
#define R__CONSTEXPR_IF_CXX14
Definition span.hxx:29
static constexpr size_t value[sizeof...(Indices)]
Definition span.hxx:69
static bool const value
Definition span.hxx:50
TLine l
Definition textangle.C:4