Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:29:19

0001 #ifndef FWCore_Utilities_get_underlying_safe_h
0002 #define FWCore_Utilities_get_underlying_safe_h
0003 
0004 /*
0005  Description:
0006 
0007  The function get_underlying(), provided by propagate_const, should not be called directly
0008  by users because it may cast away constness.
0009  This header  provides helper function(s) get_underlying_safe() to users of propagate_const<T>.
0010  The get_underlying_safe() functions avoid this issue.
0011 
0012  If called with a non-const ref argument, get_underlying_safe() simply calls get_underlying().
0013  If called with a const ref argument, get_underlying_safe() returns a pointer to const,
0014  which preserves constness, but requires copying the pointer.
0015 
0016  For non-copyable pointers, such as std::unique_ptr, it is not possible to preserve constness.
0017  so get_underlying_safe() will fail to compile if called with a const ref to a unique_ptr.
0018  This is intentional.
0019 
0020  This header can be expanded to support other smart pointers as needed.
0021 */
0022 
0023 //
0024 // Original Author:  Bill Tanenbaum
0025 //
0026 
0027 // system include files
0028 #include <memory>
0029 
0030 // user include files
0031 
0032 #include "FWCore/Utilities/interface/propagate_const.h"
0033 #include "FWCore/Utilities/interface/propagate_const_array.h"
0034 
0035 // forward declarations
0036 
0037 namespace edm {
0038 
0039   // for std::shared_ptr
0040   template <typename T>
0041   constexpr std::shared_ptr<T>& get_underlying_safe(propagate_const<std::shared_ptr<T>>& iP) {
0042     return get_underlying(iP);
0043   }
0044   template <typename T>
0045   constexpr std::shared_ptr<T const> get_underlying_safe(propagate_const<std::shared_ptr<T>> const& iP) {
0046     std::shared_ptr<T const> copy = get_underlying(iP);
0047     return copy;
0048   }
0049 
0050   template <typename T>
0051   constexpr std::shared_ptr<T[]>& get_underlying_safe(propagate_const_array<std::shared_ptr<T[]>>& iP) {
0052     return get_underlying(iP);
0053   }
0054   template <typename T>
0055   constexpr std::shared_ptr<T const []> get_underlying_safe(propagate_const_array<std::shared_ptr<T[]>> const& iP) {
0056     std::shared_ptr<T const[]> copy = get_underlying(iP);
0057     return copy;
0058   }
0059 
0060   // for bare pointer
0061   template <typename T>
0062   constexpr T*& get_underlying_safe(propagate_const<T*>& iP) {
0063     return get_underlying(iP);
0064   }
0065   template <typename T>
0066   constexpr T const* get_underlying_safe(propagate_const<T*> const& iP) {
0067     T const* copy = get_underlying(iP);
0068     return copy;
0069   }
0070 
0071   template <typename T>
0072   constexpr T* get_underlying_safe(propagate_const_array<T[]>& iP) {
0073     return get_underlying(iP);
0074   }
0075   template <typename T>
0076   constexpr T const* get_underlying_safe(propagate_const_array<T[]> const& iP) {
0077     T const* copy = get_underlying(iP);
0078     return copy;
0079   }
0080 
0081   // for std::unique_ptr
0082   template <typename T>
0083   constexpr std::unique_ptr<T>& get_underlying_safe(propagate_const<std::unique_ptr<T>>& iP) {
0084     return get_underlying(iP);
0085   }
0086   // the template below will deliberately not compile.
0087   template <typename T>
0088   constexpr std::unique_ptr<T const> get_underlying_safe(propagate_const<std::unique_ptr<T>> const& iP) {
0089     std::unique_ptr<T const> copy = get_underlying(iP);
0090     return copy;
0091   }
0092 
0093   template <typename T>
0094   constexpr std::unique_ptr<T[]>& get_underlying_safe(propagate_const_array<std::unique_ptr<T[]>>& iP) {
0095     return get_underlying(iP);
0096   }
0097   // the template below will deliberately not compile.
0098   template <typename T>
0099   constexpr std::unique_ptr<T const []> get_underlying_safe(propagate_const_array<std::unique_ptr<T[]>> const& iP) {
0100     std::unique_ptr<T const[]> copy = get_underlying(iP);
0101     return copy;
0102   }
0103 
0104 }  // namespace edm
0105 
0106 #endif