CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 
32 #include "boost/shared_ptr.hpp"
33 
35 
36 // forward declarations
37 
38 namespace edm {
39 
40  // for std::shared_ptr
41  template<typename T> std::shared_ptr<T>& get_underlying_safe(propagate_const<std::shared_ptr<T>>& iP) {return get_underlying(iP);}
42  template<typename T> std::shared_ptr<T const> get_underlying_safe(propagate_const<std::shared_ptr<T>> const& iP ) {std::shared_ptr<T const> copy = get_underlying(iP); return copy;}
43 
44  // for bare pointer
45  template<typename T> T*& get_underlying_safe(propagate_const<T*>& iP) {return get_underlying(iP);}
46  template<typename T> T const* get_underlying_safe(propagate_const<T*> const& iP) {T const* copy = get_underlying(iP); return copy;}
47 
48  // for boost::shared_ptr
49  template<typename T> boost::shared_ptr<T>& get_underlying_safe(propagate_const<boost::shared_ptr<T>>& iP) {return get_underlying(iP);}
50  template<typename T> boost::shared_ptr<T const> get_underlying_safe(propagate_const<boost::shared_ptr<T>> const& iP) {boost::shared_ptr<T const> copy = get_underlying(iP); return copy;}
51 
52  // for std::unique_ptr
53  template<typename T> std::unique_ptr<T>& get_underlying_safe(propagate_const<std::unique_ptr<T>>& iP) {return get_underlying(iP);}
54  // This template below will deliberately not compile.
55  template<typename T> std::unique_ptr<T const> get_underlying_safe(propagate_const<std::unique_ptr<T>> const& iP) {std::unique_ptr<T const> copy = get_underlying(iP); return copy;}
56 
57 }
58 
59 #endif
T & get_underlying(propagate_const< T > &)
std::shared_ptr< T > & get_underlying_safe(propagate_const< std::shared_ptr< T >> &iP)
long double T