CMS 3D CMS Logo

get_underlying_safe.h
Go to the documentation of this file.
1 #ifndef FWCore_Utilities_get_underlying_safe_h
2 #define FWCore_Utilities_get_underlying_safe_h
3 
4 /*
5  Description:
6 
7  The function get_underlying(), provided by propagate_const, should not be called directly
8  by users because it may cast away constness.
9  This header provides helper function(s) get_underlying_safe() to users of propagate_const<T>.
10  The get_underlying_safe() functions avoid this issue.
11 
12  If called with a non-const ref argument, get_underlying_safe() simply calls get_underlying().
13  If called with a const ref argument, get_underlying_safe() returns a pointer to const,
14  which preserves constness, but requires copying the pointer.
15 
16  For non-copyable pointers, such as std::unique_ptr, it is not possible to preserve constness.
17  so get_underlying_safe() will fail to compile if called with a const ref to a unique_ptr.
18  This is intentional.
19 
20  This header can be expanded to support other smart pointers as needed.
21 */
22 
23 //
24 // Original Author: Bill Tanenbaum
25 //
26 
27 // system include files
28 #include <memory>
29 
30 // user include files
31 
34 
35 // forward declarations
36 
37 namespace edm {
38 
39  // for std::shared_ptr
40  template <typename T>
41  constexpr std::shared_ptr<T>& get_underlying_safe(propagate_const<std::shared_ptr<T>>& iP) {
42  return get_underlying(iP);
43  }
44  template <typename T>
45  constexpr std::shared_ptr<T const> get_underlying_safe(propagate_const<std::shared_ptr<T>> const& iP) {
46  std::shared_ptr<T const> copy = get_underlying(iP);
47  return copy;
48  }
49 
50  template <typename T>
51  constexpr std::shared_ptr<T[]>& get_underlying_safe(propagate_const_array<std::shared_ptr<T[]>>& iP) {
52  return get_underlying(iP);
53  }
54  template <typename T>
55  constexpr std::shared_ptr<T const []> get_underlying_safe(propagate_const_array<std::shared_ptr<T[]>> const& iP) {
56  std::shared_ptr<T const[]> copy = get_underlying(iP);
57  return copy;
58  }
59 
60  // for bare pointer
61  template <typename T>
63  return get_underlying(iP);
64  }
65  template <typename T>
66  constexpr T const* get_underlying_safe(propagate_const<T*> const& iP) {
67  T const* copy = get_underlying(iP);
68  return copy;
69  }
70 
71  template <typename T>
73  return get_underlying(iP);
74  }
75  template <typename T>
76  constexpr T const* get_underlying_safe(propagate_const_array<T[]> const& iP) {
77  T const* copy = get_underlying(iP);
78  return copy;
79  }
80 
81  // for std::unique_ptr
82  template <typename T>
83  constexpr std::unique_ptr<T>& get_underlying_safe(propagate_const<std::unique_ptr<T>>& iP) {
84  return get_underlying(iP);
85  }
86  // the template below will deliberately not compile.
87  template <typename T>
88  constexpr std::unique_ptr<T const> get_underlying_safe(propagate_const<std::unique_ptr<T>> const& iP) {
89  std::unique_ptr<T const> copy = get_underlying(iP);
90  return copy;
91  }
92 
93  template <typename T>
94  constexpr std::unique_ptr<T[]>& get_underlying_safe(propagate_const_array<std::unique_ptr<T[]>>& iP) {
95  return get_underlying(iP);
96  }
97  // the template below will deliberately not compile.
98  template <typename T>
99  constexpr std::unique_ptr<T const []> get_underlying_safe(propagate_const_array<std::unique_ptr<T[]>> const& iP) {
100  std::unique_ptr<T const[]> copy = get_underlying(iP);
101  return copy;
102  }
103 
104 } // namespace edm
105 
106 #endif
constexpr std::shared_ptr< T > & get_underlying_safe(propagate_const< std::shared_ptr< T >> &iP)
std::unique_ptr< T, impl::DeviceDeleter > unique_ptr
constexpr T & get_underlying(propagate_const< T > &)
HLT enums.
long double T