1+ #include < iostream>
2+ #include " smart_pointer_type_trait.hpp"
3+
4+ template < typename Ptr >
5+ auto get_raw_pointer ( Ptr& ptr )
6+ {
7+ if constexpr ( std::is_pointer_v< Ptr > ) return ptr;
8+ else return ptr.operator ->();
9+ }
10+
11+ template < typename Ty, typename Ptr >
12+ class pointer_impl
13+ {
14+ public:
15+ void reset ( Ty* target = nullptr )
16+ {
17+ if constexpr ( is_smart_ptr_v< Ptr > ) impl.reset ( target );
18+ else impl = target;
19+ }
20+
21+ void release () { impl = nullptr ; }
22+
23+ Ty* get () noexcept { return operator ->(); }
24+ const Ty* get () const noexcept { return operator ->(); }
25+
26+ decltype ( auto ) get_deleter() noexcept
27+ {
28+ static_assert ( is_smart_ptr_v< Ptr >, " pointer_impl< Ty, Ptr >::get_deleter(): Ptr was not a smart pointer." );
29+ return impl.get_deleter ();
30+ }
31+ decltype ( auto ) get_deleter() const noexcept
32+ {
33+ static_assert ( is_smart_ptr_v< Ptr >, " pointer_impl< Ty, Ptr >::get_deleter(): Ptr was not a smart pointer." );
34+ return impl.get_deleter ();
35+ }
36+
37+ Ty& operator *() noexcept { return *impl; }
38+ const Ty& operator *() const noexcept { return *impl; }
39+ Ty* operator ->() noexcept { return get_raw_pointerr ( impl ); }
40+ const Ty* operator ->() const noexcept { return get_raw_pointer ( impl ); }
41+ operator bool () const noexcept { return static_cast < bool >( get_raw_pointer ( impl ) ); }
42+
43+ // special member functions
44+ pointer_impl ( Ty* impl = nullptr ) : impl{ impl } {}
45+ ~pointer_impl () { impl = nullptr ; }
46+
47+ private:
48+ Ptr impl;
49+ };
50+
51+ // ======================================================
52+ // ******************************************************
53+ // Decoupling by using keyword.
54+ // memory allocation policy has only-one dependancy, this code.
55+ // ======================================================
56+ template < typename Ty >
57+ using pointer = pointer_impl< Ty, std::unique_ptr< Ty > >; // can change to diffrent pointer
58+ // If you add more pointer object, ( and similar type trait )
59+ // can also change to the pointer object.
60+ // ******************************************************
61+ // ======================================================
62+
63+ template < typename Ty, typename ... Args >
64+ auto make ( Args&& ... args )
65+ {
66+ return pointer< Ty >{ new Ty{ std::forward< Args >( args )... } };
67+ }
68+
69+ struct INT
70+ {
71+ INT ( int impl = 0 ) : impl{ impl } { std::cout << " INT constructor called\n " ; }
72+ ~INT () { std::cout << " INT destructor called\n " ; }
73+ INT ( const INT& other ) : impl{ other.impl } { std::cout << " INT copy constructor called\n " ; }
74+ INT& operator =( const INT& other )
75+ {
76+ if ( this != &other )
77+ {
78+ std::cout << " INT copy allocator called\n " ;
79+ impl = other.impl ;
80+ }
81+
82+ return *this ;
83+ }
84+ INT ( INT&& other ) : impl{ other.impl } { std::cout << " INT move constructor called\n " ; }
85+ INT& operator =( INT&& other )
86+ {
87+ if ( this != &other )
88+ {
89+ std::cout << " INT move allocator called\n " ;
90+ impl = other.impl ;
91+ }
92+
93+ return *this ;
94+ }
95+ operator int () { return impl; }
96+
97+ int impl;
98+ };
99+
100+ int main ()
101+ {
102+ std::cout << " must call constructor ==================\n " ;
103+ auto a = make< INT >( 4 );
104+ std::cout << " ========================================\n\n\n " ;
105+
106+ std::cout << " get_deleter() call =====================\n " ;
107+ std::cout << typeid ( a.get_deleter () ).name () << ' \n ' ;
108+ std::cout << " ========================================\n\n\n " ;
109+
110+ std::cout << " print value ============================\n " ;
111+ std::cout << " value: " << *a << ' \n ' ;
112+ std::cout << " ========================================\n\n\n " ;
113+
114+ std::cout << " must call constructor and destructor ===\n " ;
115+ a.reset ( new INT{ 5 } );
116+ std::cout << " ========================================\n\n\n " ;
117+
118+ std::cout << " print value ============================\n " ;
119+ std::cout << " value: " << *a << ' \n ' ;
120+ std::cout << " ========================================\n\n\n " ;
121+
122+ std::cout << " must call destructor ===================\n " ;
123+ }
0 commit comments