Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RooSpan.h
Go to the documentation of this file.
1 // Author: Stephan Hageboeck, CERN 7 Feb 2019
2 
3 /*****************************************************************************
4  * RooFit
5  * Authors: *
6  * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7  * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8  * *
9  * Copyright (c) 2000-2019, Regents of the University of California *
10  * and Stanford University. All rights reserved. *
11  * *
12  * Redistribution and use in source and binary forms, *
13  * with or without modification, are permitted according to the terms *
14  * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15  *****************************************************************************/
16 
17 #ifndef ROOFIT_ROOFITCORE_INC_ROOSPAN_H_
18 #define ROOFIT_ROOFITCORE_INC_ROOSPAN_H_
19 
20 #include "ROOT/RSpan.hxx"
21 
22 ////////////////////////////////////////////////////////////////////////////
23 /// A simple container to hold a batch of data values.
24 /// It can operate in two modes:
25 /// * Span: It holds only a pointer to the storage held by another object
26 /// like a std::span does.
27 /// * Temp data: It holds its own data, and exposes the span.
28 /// This mode is necessary to ship data that are not available in
29 /// a contiguous storage like e.g. data from a TTree. This means, however, that
30 /// data have to be copied, and only live as long as the span.
31 template<class T>
32 class RooSpan {
33 public:
34  using iterator = typename std::span<T>::iterator;
35  using value_type = typename std::remove_cv<T>::type;
36 
37  constexpr RooSpan() :
38  _auxStorage{},
39  _span{} { }
40 
41  constexpr RooSpan(RooSpan&& other) :
42  _auxStorage{std::move(other._auxStorage)},
43  _span{other._span.data(), other._span.size()}
44  { }
45 
46  constexpr RooSpan(const RooSpan& other) :
47  _auxStorage{other._auxStorage},
48  _span{other._span}
49  { }
50 
51 
52  /// Conversion constructor from <T> to <const T>
53  template<typename NON_CONST_T,
54  typename = typename std::enable_if<std::is_same<const NON_CONST_T, T>::value>::type >
55  constexpr RooSpan(const RooSpan<NON_CONST_T>& other) :
56  _auxStorage{},
57  _span{other.data(), other.size()}
58  { }
59 
60  /// Construct from a range. Data held by foreign object.
61  template < class InputIterator>
62  constexpr RooSpan(InputIterator beginIn, InputIterator endIn) :
63  _auxStorage{},
64  _span{beginIn, endIn}
65  { }
66 
67 
68  /// Construct from start and end pointers.
69  constexpr RooSpan(typename std::span<T>::pointer beginIn,
70  typename std::span<T>::pointer endIn) :
71  _auxStorage{},
72  _span{beginIn, endIn}
73  { }
74 
75 
76  /// Construct from start pointer and size.
77  constexpr RooSpan(typename std::span<T>::pointer beginIn,
78  typename std::span<T>::index_type sizeIn) :
79  _auxStorage{},
80  _span{beginIn, sizeIn}
81  { }
82 
83 
84  constexpr RooSpan(const std::vector<typename std::remove_cv<T>::type>& vec) noexcept :
85  _auxStorage{},
86  _span{vec}
87  { }
88 
89  constexpr RooSpan(std::vector<typename std::remove_cv<T>::type>& vec) noexcept :
90  _auxStorage{},
91  _span{vec}
92  { }
93 
94 
95  /// Hand data over to this span. This will mean that the data will get
96  /// deleted when it goes out of scope. Try to avoid this because
97  /// unnecessary copies will be made.
98  constexpr RooSpan(std::vector<value_type>&& payload) :
99  _auxStorage{new std::vector<value_type>(std::forward<std::vector<value_type>>(payload))},
100  _span{_auxStorage->begin(), _auxStorage->end()}
101  { }
102 
103 
104  RooSpan<T>& operator=(const RooSpan<T>& other) = default;
105 
106 
107  constexpr typename std::span<T>::iterator begin() const {
108  return _span.begin();
109  }
110 
111  constexpr typename std::span<T>::iterator end() const {
112  return _span.end();
113  }
114 
115  constexpr typename std::span<T>::pointer data() const {
116  return _span.data();
117  }
118 
119  constexpr typename std::span<T>::reference operator[](typename std::span<T>::index_type i) const noexcept {
120  return _span[i];
121  }
122 
123  constexpr typename std::span<T>::index_type size() const noexcept {
124  return _span.size();
125  }
126 
127  constexpr bool empty() const noexcept {
128  return _span.empty();
129  }
130 
131  constexpr bool isBatch() const noexcept {
132  return true;
133  }
134 
135 
136  ///Test if the span overlaps with `other`.
137  template <class Span_t>
138  bool overlaps(const Span_t& other) const {
139  return insideSpan(other.begin()) || insideSpan(other.end()-1)
140  || other.insideSpan(begin()) || other.insideSpan(end()-1);
141  }
142 
143  ///Test if the given pointer/iterator is inside the span.
144  template <typename ptr_t>
145  bool insideSpan(ptr_t ptr) const {
146  return begin() <= ptr && ptr < end();
147  }
148 
149 private:
150 
151  /// If a class does not own a contiguous block of memory, which
152  /// could be used to create a span, the memory has to be kept alive
153  /// until all referring spans are destroyed.
154  std::shared_ptr<std::vector<value_type>> _auxStorage;
155  std::span<T> _span;
156 };
157 
158 
159 #endif /* ROOFIT_ROOFITCORE_INC_ROOSPAN_H_ */