Replace NULL with nullptr
[libcds.git] / cds / os / alloc_aligned.h
1 //$$CDS-header$$
2
3 #ifndef __CDS_OS_ALLOC_ALIGNED_H
4 #define __CDS_OS_ALLOC_ALIGNED_H
5
6 #include <cds/details/defs.h>
7
8 #if CDS_OS_TYPE == CDS_OS_WIN32 || CDS_OS_TYPE == CDS_OS_WIN64 || CDS_OS_TYPE == CDS_OS_MINGW
9 #   include <cds/os/win/alloc_aligned.h>
10 #elif CDS_OS_TYPE == CDS_OS_LINUX
11 #   include <cds/os/linux/alloc_aligned.h>
12 #elif CDS_OS_TYPE == CDS_OS_SUN_SOLARIS
13 #   include <cds/os/sunos/alloc_aligned.h>
14 #elif CDS_OS_TYPE == CDS_OS_HPUX
15 #   include <cds/os/hpux/alloc_aligned.h>
16 #elif CDS_OS_TYPE == CDS_OS_AIX
17 #   include <cds/os/aix/alloc_aligned.h>
18 #elif CDS_OS_TYPE == CDS_OS_FREE_BSD || CDS_OS_TYPE == CDS_OS_OPEN_BSD || CDS_OS_TYPE == CDS_OS_NET_BSD
19 #   include <cds/os/free_bsd/alloc_aligned.h>
20 #elif CDS_OS_TYPE == CDS_OS_OSX || CDS_OS_TYPE == CDS_OS_PTHREAD
21 #   include <cds/os/posix/alloc_aligned.h>
22 #else
23 #   error Unknown OS. Compilation aborted
24 #endif
25
26 #include <memory>
27 #include <cds/details/is_aligned.h>
28 #include <cds/algo/int_algo.h>
29
30 namespace cds {
31     /// OS specific wrappers
32     /**
33         This namespace contains OS-specific implementations.
34         Usually, the sub-namespaces contain OS-specific wrappers for a feature.
35
36         Typical usage pattern:
37         \code
38             namespace cds {
39             namespace OS {
40                 namespace Linux {
41                     class Feature {
42                         // ...
43                     };
44                 }
45
46                 // import Linux::Feature class into cds::OS namespace
47                 using Linux::Feature;
48                 // now, cds::OS::Feature refers to cds::OS::Linux::Feature
49             }
50             }
51         \endcode
52     */
53     namespace OS {
54         /// Aligned allocator
55         /**
56             This allocator is intended for allocating of an aligned memory block. It uses wrappers around platform-specific
57             function for allocating and deallocating the block of memory:
58             \li \p aligned_malloc for allocating
59             \li \p aligned_free for deallocating
60
61             The \p aligned_malloc function wraps:
62             \li \p for Win: \p _aligned_malloc function
63             \li \p for other OSes: \p posix_memalign / \p memalign function
64
65             The \p aligned_free function wraps:
66             \li \p for Win: \p _aligned_free function
67             \li \p for other OSes: \p free function
68
69             This class should not be used directly. Use cds::details::AlignedAllocator instead.
70         */
71         template <typename T>
72         class aligned_allocator
73         {
74             typedef std::allocator<T>  prototype    ;   ///< prototype (the source of typedefs)
75         public:
76             typedef typename prototype::value_type       value_type      ;  ///< value type
77             typedef typename prototype::pointer          pointer         ;  ///< pointer to value type
78             typedef typename prototype::reference        reference       ;  ///< value reference type
79             typedef typename prototype::const_pointer    const_pointer   ;  ///< const pointer to value type
80             typedef typename prototype::const_reference  const_reference ;  ///< const value reference type
81
82             typedef typename prototype::size_type        size_type       ;  ///< size type
83             typedef typename prototype::difference_type  difference_type ;  ///< difference type
84
85             /// convert an aligned_allocator<T> to an aligned_allocator<OTHER>
86             template<class OTHER>
87             struct rebind
88             {
89                 typedef aligned_allocator<OTHER> other; ///< Rebinding result
90             };
91
92         public:
93             /// return address of mutable \p v
94             pointer address(reference v) const
95             {
96                 prototype a;
97                 return a.address( v );
98             }
99
100             /// return address of nonmutable \p v
101             const_pointer address(const_reference v) const
102             {
103                 prototype a;
104                 return a.address( v );
105             }
106
107             // construct default allocator (do nothing)
108             aligned_allocator() throw()
109             {}
110
111             /// construct by copying (do nothing)
112             aligned_allocator(const aligned_allocator<T>&) throw()
113             {}
114
115             /// construct from a related allocator (do nothing)
116             template <class OTHER>
117             aligned_allocator(const aligned_allocator<OTHER>&) throw()
118             {}
119
120             /// assign from a related allocator (do nothing)
121             template <class OTHER>
122             aligned_allocator<T>& operator=(const aligned_allocator<OTHER>&)
123             {
124                 return (*this);
125             }
126
127             /// deallocate object at \p ptr, ignore size
128             void deallocate(pointer ptr, size_type)
129             {
130                 cds::OS::aligned_free( ptr );
131             }
132
133             /// allocate array of \p nCount elements
134             /**
135                 The address returned is aligned by \p nAlign boundary.
136                 \p nAlign parameter should be power of 2.
137
138                 The function guarantees the alignment for first element of array only.
139                 To guarantee the alignment for each element of the array the size of an object of type \p T must be multiple of \p nAlign:
140                 \code
141                 sizeof(T) % nAlign == 0
142                 \endcode
143             */
144             pointer allocate( size_type nAlign, size_type nCount )
145             {
146                 assert( cds::beans::is_power2( nAlign ) );
147                 pointer p = reinterpret_cast<T *>( cds::OS::aligned_malloc( sizeof(T) * nCount, nAlign ) );
148                 assert( cds::details::is_aligned( p, nAlign ));
149                 return p;
150             }
151
152             /// allocate array of \p nCount elements, ignore hint
153             /**
154                 The address returned is aligned by \p nAlign boundary.
155                 \p nAlign parameter should be power of 2.
156
157                 The function guarantees alignment for first element of array only.
158             */
159             pointer allocate(size_type nAlign, size_type nCount, const void *)
160             {
161                 return ( allocate( nAlign, nCount ) );
162             }
163
164             /// construct object at \p ptr with value \p val
165             void construct(pointer ptr, const T& val)
166             {
167                 prototype a;
168                 a.construct( ptr, val );
169             }
170
171             /// destroy object at \p ptr
172             void destroy(pointer ptr)
173             {
174                 prototype a;
175                 a.destroy( ptr );
176             }
177
178             /// estimate maximum array size
179             size_type max_size() const throw()
180             {
181                 prototype a;
182                 return a.max_size();
183             }
184         };
185     }   // namespace OS
186 }  // namespace cds
187
188 #endif  // #ifndef __CDS_OS_ALLOC_ALIGNED_H