File indexing completed on 2024-04-06 12:13:12
0001 #ifndef FWCore_Utilities_propagate_const_h
0002 #define FWCore_Utilities_propagate_const_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include <type_traits>
0023 #include <utility>
0024
0025
0026
0027
0028
0029 namespace edm {
0030
0031 template <typename T>
0032 class propagate_const;
0033
0034 template <typename T>
0035 constexpr T& get_underlying(propagate_const<T>&);
0036 template <typename T>
0037 constexpr T const& get_underlying(propagate_const<T> const&);
0038
0039 template <typename T>
0040 class propagate_const {
0041 public:
0042 friend constexpr T& get_underlying<T>(propagate_const<T>&);
0043 friend constexpr T const& get_underlying<T>(propagate_const<T> const&);
0044
0045 using element_type = typename std::remove_reference<decltype(*std::declval<T&>())>::type;
0046
0047 constexpr propagate_const() = default;
0048
0049 constexpr propagate_const(propagate_const<T>&&) = default;
0050 propagate_const(propagate_const<T> const&) = delete;
0051 template <typename U>
0052 constexpr propagate_const(U&& iValue) : m_value(std::forward<U>(iValue)) {}
0053
0054 constexpr propagate_const<T>& operator=(propagate_const&&) = default;
0055 propagate_const<T>& operator=(propagate_const<T> const&) = delete;
0056
0057 template <typename U>
0058 constexpr propagate_const& operator=(U&& iValue) {
0059 m_value = std::forward<U>(iValue);
0060 return *this;
0061 }
0062
0063
0064 constexpr element_type const* get() const { return to_raw_pointer(m_value); }
0065 constexpr element_type const* operator->() const { return this->get(); }
0066 constexpr element_type const& operator*() const { return *m_value; }
0067
0068 constexpr operator element_type const*() const { return this->get(); }
0069
0070
0071 constexpr element_type* get() { return to_raw_pointer(m_value); }
0072 constexpr element_type* operator->() { return this->get(); }
0073 constexpr element_type& operator*() { return *m_value; }
0074
0075 constexpr operator element_type*() { return this->get(); }
0076
0077 private:
0078 template <typename Up>
0079 static constexpr element_type* to_raw_pointer(Up* u) {
0080 return u;
0081 }
0082
0083 template <typename Up>
0084 static constexpr element_type* to_raw_pointer(Up& u) {
0085 return u.get();
0086 }
0087
0088 template <typename Up>
0089 static constexpr const element_type* to_raw_pointer(const Up* u) {
0090 return u;
0091 }
0092
0093 template <typename Up>
0094 static constexpr const element_type* to_raw_pointer(const Up& u) {
0095 return u.get();
0096 }
0097
0098
0099 T m_value;
0100 };
0101
0102 template <typename T>
0103 constexpr T& get_underlying(propagate_const<T>& iP) {
0104 return iP.m_value;
0105 }
0106 template <typename T>
0107 constexpr T const& get_underlying(propagate_const<T> const& iP) {
0108 return iP.m_value;
0109 }
0110
0111 }
0112
0113 #endif