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