CMS 3D CMS Logo

propagate_const_array.h
Go to the documentation of this file.
1 #ifndef FWCore_Utilities_interface_propagate_const_array_h
2 #define FWCore_Utilities_interface_propagate_const_array_h
3 // -*- C++ -*-
4 //
5 // Package: FWCore/Utilities
6 // Class : propagate_const_array
7 // Description: Propagate const to array-like objects. Based on C++ experimental std::propagate_const.
8 // If used with an array of incomplete type, edm::propagate_const_array can only be declared
9 // and assigned to nullptr, but not assigned to an actual object or dereferenced.
10 
11 // system include files
12 #include <cstddef>
13 #include <type_traits>
14 #include <utility>
15 
16 // user include files
17 
18 // forward declarations
19 
20 namespace edm {
21 
22  namespace impl {
23 
24  // check if a type T has a subscript operator T[N]
25  template <typename, typename = void>
26  struct has_subscript_operator : std::false_type {};
27 
28  template <typename T>
29  struct has_subscript_operator<T, std::void_t<decltype(std::declval<T&>()[0])>> : std::true_type {};
30 
31  template <typename T>
33 
34  // for a type T, return the type of the return value of the subscript operator T[N]
35  template <typename T, typename = void, typename = void>
36  struct subscript_type {};
37 
38  // the specialisations for arrays allow supporting incomplete types
39  template <typename T>
40  struct subscript_type<T[]> {
41  using type = T;
42  };
43 
44  template <typename T, int N>
45  struct subscript_type<T[N]> {
46  using type = T;
47  };
48 
49  // for non-array types that implement the subscript operator[], a complete type is needed
50  template <typename T>
51  struct subscript_type<T, std::enable_if_t<not std::is_array_v<T>>, std::enable_if_t<has_subscript_operator_v<T>>> {
52  using type = typename std::remove_reference<decltype(std::declval<T&>()[0])>::type;
53  };
54 
55  template <typename T>
57 
58  } // namespace impl
59 
60  template <typename T>
62 
63  template <typename T>
64  constexpr std::decay_t<T>& get_underlying(propagate_const_array<T>&);
65  template <typename T>
66  constexpr std::decay_t<T> const& get_underlying(propagate_const_array<T> const&);
67 
68  template <typename T>
69  class propagate_const_array {
70  public:
71  friend constexpr std::decay_t<T>& get_underlying<T>(propagate_const_array<T>&);
72  friend constexpr std::decay_t<T> const& get_underlying<T>(propagate_const_array<T> const&);
73 
74  template <typename U>
75  friend class propagate_const_array;
76 
78 
79  constexpr propagate_const_array() = default;
80  constexpr propagate_const_array(propagate_const_array<T>&&) = default;
82  template <typename U>
83  constexpr propagate_const_array(U&& u) : m_value(std::forward<U>(u)) {}
84 
87 
88  template <typename U>
90  static_assert(std::is_convertible_v<std::decay_t<U>, std::decay_t<T>>,
91  "Cannot assign propagate_const_array<> of incompatible types");
92  m_value = other.m_value;
93  return *this;
94  }
95 
96  template <typename U>
97  constexpr propagate_const_array& operator=(U&& u) {
98  m_value = std::forward<U>(u);
99  return *this;
100  }
101 
102  // ---------- const member functions ---------------------
103  constexpr element_type const* get() const { return &m_value[0]; }
104  constexpr element_type const& operator[](std::ptrdiff_t pos) const { return m_value[pos]; }
105 
106  constexpr operator element_type const *() const { return this->get(); }
107 
108  // ---------- member functions ---------------------------
109  constexpr element_type* get() { return &m_value[0]; }
110  constexpr element_type& operator[](std::ptrdiff_t pos) { return m_value[pos]; }
111 
112  constexpr operator element_type*() { return this->get(); }
113 
114  private:
115  // ---------- member data --------------------------------
116  std::decay_t<T> m_value;
117  };
118 
119  template <typename T>
120  constexpr std::decay_t<T>& get_underlying(propagate_const_array<T>& iP) {
121  return iP.m_value;
122  }
123 
124  template <typename T>
125  constexpr std::decay_t<T> const& get_underlying(propagate_const_array<T> const& iP) {
126  return iP.m_value;
127  }
128 
129 } // namespace edm
130 
131 #endif // FWCore_Utilities_interface_propagate_const_array_h
edm
HLT enums.
Definition: AlignableModifier.h:19
pos
Definition: PixelAliasList.h:18
edm::impl::subscript_type
Definition: propagate_const_array.h:36
edm::propagate_const_array::get
constexpr element_type * get()
Definition: propagate_const_array.h:109
edm::propagate_const_array::m_value
std::decay_t< T > m_value
Definition: propagate_const_array.h:116
edm::impl::subscript_type< T[]>::type
T type
Definition: propagate_const_array.h:41
edm::impl::has_subscript_operator_v
constexpr auto has_subscript_operator_v
Definition: propagate_const_array.h:32
edm::propagate_const_array::propagate_const_array
constexpr propagate_const_array()=default
N
#define N
Definition: blowfish.cc:9
edm::propagate_const_array::operator=
constexpr propagate_const_array & operator=(U &&u)
Definition: propagate_const_array.h:97
trackingPlots.other
other
Definition: trackingPlots.py:1464
mitigatedMETSequence_cff.U
U
Definition: mitigatedMETSequence_cff.py:36
edm::impl::subscript_type< T[N]>::type
T type
Definition: propagate_const_array.h:46
edm::get_underlying
constexpr T & get_underlying(propagate_const< T > &)
Definition: propagate_const.h:103
edm::propagate_const_array::operator=
constexpr propagate_const_array & operator=(propagate_const_array< U > &other)
Definition: propagate_const_array.h:89
edm::propagate_const_array
Definition: propagate_const_array.h:61
edm::propagate_const_array::propagate_const_array
constexpr propagate_const_array(U &&u)
Definition: propagate_const_array.h:83
edm::propagate_const_array::operator[]
constexpr element_type const & operator[](std::ptrdiff_t pos) const
Definition: propagate_const_array.h:104
edm::propagate_const_array::get
constexpr element_type const * get() const
Definition: propagate_const_array.h:103
impl
Definition: trackAlgoPriorityOrder.h:18
std
Definition: JetResolutionObject.h:76
edm::propagate_const_array::operator[]
constexpr element_type & operator[](std::ptrdiff_t pos)
Definition: propagate_const_array.h:110
edm::propagate_const_array< cms::cuda::device::unique_ptr< double[]> >::element_type
typename impl::subscript_type_t< cms::cuda::device::unique_ptr< double[]> > element_type
Definition: propagate_const_array.h:77
edm::impl::has_subscript_operator
Definition: propagate_const_array.h:26
T
long double T
Definition: Basic3DVectorLD.h:48
edm::propagate_const_array::operator=
constexpr propagate_const_array< T > & operator=(propagate_const_array &&)=default
edm::impl::subscript_type< T, std::enable_if_t< not std::is_array_v< T > >, std::enable_if_t< has_subscript_operator_v< T > > >::type
typename std::remove_reference< decltype(std::declval< T & >()[0])>::type type
Definition: propagate_const_array.h:52
edm::impl::subscript_type_t
typename subscript_type< T >::type subscript_type_t
Definition: propagate_const_array.h:56