Removed trailing spaces
[libcds.git] / cds / os / alloc_aligned.h
1 /*
2     This file is a part of libcds - Concurrent Data Structures library
3
4     (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
5
6     Source code repo: http://github.com/khizmax/libcds/
7     Download: http://sourceforge.net/projects/libcds/files/
8
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions are met:
11
12     * Redistributions of source code must retain the above copyright notice, this
13       list of conditions and the following disclaimer.
14
15     * Redistributions in binary form must reproduce the above copyright notice,
16       this list of conditions and the following disclaimer in the documentation
17       and/or other materials provided with the distribution.
18
19     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23     FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28     OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #ifndef CDSLIB_OS_ALLOC_ALIGNED_H
32 #define CDSLIB_OS_ALLOC_ALIGNED_H
33
34 #include <cds/details/defs.h>
35
36 #if CDS_OS_TYPE == CDS_OS_WIN32 || CDS_OS_TYPE == CDS_OS_WIN64 || CDS_OS_TYPE == CDS_OS_MINGW
37 #   include <cds/os/win/alloc_aligned.h>
38 #elif CDS_OS_TYPE == CDS_OS_LINUX
39 #   include <cds/os/linux/alloc_aligned.h>
40 #elif CDS_OS_TYPE == CDS_OS_SUN_SOLARIS
41 #   include <cds/os/sunos/alloc_aligned.h>
42 #elif CDS_OS_TYPE == CDS_OS_HPUX
43 #   include <cds/os/hpux/alloc_aligned.h>
44 #elif CDS_OS_TYPE == CDS_OS_AIX
45 #   include <cds/os/aix/alloc_aligned.h>
46 #elif CDS_OS_TYPE == CDS_OS_FREE_BSD || CDS_OS_TYPE == CDS_OS_OPEN_BSD || CDS_OS_TYPE == CDS_OS_NET_BSD
47 #   include <cds/os/free_bsd/alloc_aligned.h>
48 #elif CDS_OS_TYPE == CDS_OS_OSX || CDS_OS_TYPE == CDS_OS_PTHREAD
49 #   include <cds/os/posix/alloc_aligned.h>
50 #else
51 #   error Unknown OS. Compilation aborted
52 #endif
53
54 #include <memory>
55 #include <cds/details/is_aligned.h>
56 #include <cds/algo/int_algo.h>
57 #include <cds/details/throw_exception.h>
58
59 namespace cds {
60     /// OS specific wrappers
61     /**
62         This namespace contains OS-specific implementations.
63         Usually, the sub-namespaces contain OS-specific wrappers for a feature.
64
65         Typical usage pattern:
66         \code
67             namespace cds {
68             namespace OS {
69                 namespace Linux {
70                     class Feature {
71                         // ...
72                     };
73                 }
74
75                 // import Linux::Feature class into cds::OS namespace
76                 using Linux::Feature;
77                 // now, cds::OS::Feature refers to cds::OS::Linux::Feature
78             }
79             }
80         \endcode
81     */
82     namespace OS {
83         /// Aligned allocator
84         /**
85             This allocator is intended for allocating of an aligned memory block. It uses wrappers around platform-specific
86             function for allocating and deallocating the block of memory:
87             \li \p aligned_malloc for allocating
88             \li \p aligned_free for deallocating
89
90             The \p aligned_malloc function wraps:
91             \li \p for Win: \p _aligned_malloc function
92             \li \p for other OSes: \p posix_memalign / \p memalign function
93
94             The \p aligned_free function wraps:
95             \li \p for Win: \p _aligned_free function
96             \li \p for other OSes: \p free function
97
98             This class should not be used directly. Use cds::details::AlignedAllocator instead.
99         */
100         template <typename T>
101         class aligned_allocator
102         {
103             typedef std::allocator<T>  prototype    ;   ///< prototype (the source of typedefs)
104         public:
105             typedef typename prototype::value_type       value_type      ;  ///< value type
106             typedef typename prototype::pointer          pointer         ;  ///< pointer to value type
107             typedef typename prototype::reference        reference       ;  ///< value reference type
108             typedef typename prototype::const_pointer    const_pointer   ;  ///< const pointer to value type
109             typedef typename prototype::const_reference  const_reference ;  ///< const value reference type
110
111             typedef typename prototype::size_type        size_type       ;  ///< size type
112             typedef typename prototype::difference_type  difference_type ;  ///< difference type
113
114             /// convert an aligned_allocator<T> to an aligned_allocator<OTHER>
115             template<class OTHER>
116             struct rebind
117             {
118                 typedef aligned_allocator<OTHER> other; ///< Rebinding result
119             };
120
121         public:
122             /// return address of mutable \p v
123             pointer address(reference v) const
124             {
125                 prototype a;
126                 return a.address( v );
127             }
128
129             /// return address of nonmutable \p v
130             const_pointer address(const_reference v) const
131             {
132                 prototype a;
133                 return a.address( v );
134             }
135
136             // construct default allocator (do nothing)
137             aligned_allocator() CDS_NOEXCEPT
138             {}
139
140             /// construct by copying (do nothing)
141             aligned_allocator(const aligned_allocator<T>&) CDS_NOEXCEPT
142             {}
143
144             /// construct from a related allocator (do nothing)
145             template <class OTHER>
146             aligned_allocator(const aligned_allocator<OTHER>&) CDS_NOEXCEPT
147             {}
148
149             /// assign from a related allocator (do nothing)
150             template <class OTHER>
151             aligned_allocator<T>& operator=(const aligned_allocator<OTHER>&)
152             {
153                 return (*this);
154             }
155
156             /// deallocate object at \p ptr, ignore size
157             void deallocate(pointer ptr, size_type)
158             {
159                 cds::OS::aligned_free( ptr );
160             }
161
162             /// allocate array of \p nCount elements
163             /**
164                 The address returned is aligned by \p nAlign boundary.
165                 \p nAlign parameter should be power of 2.
166
167                 The function guarantees the alignment for first element of array only.
168                 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:
169                 \code
170                 sizeof(T) % nAlign == 0
171                 \endcode
172
173                 The function, like operator \p new does not return \p nullptr.
174                 In no memory situation the function throws \p std::bad_alloc exception.
175             */
176             pointer allocate( size_type nAlign, size_type nCount )
177             {
178                 assert( cds::beans::is_power2( nAlign ));
179                 pointer p = reinterpret_cast<T *>( cds::OS::aligned_malloc( sizeof(T) * nCount, nAlign ));
180                 if ( !p )
181                     CDS_THROW_EXCEPTION( std::bad_alloc());
182                 assert( cds::details::is_aligned( p, nAlign ));
183                 return p;
184             }
185
186             /// allocate array of \p nCount elements, ignore hint
187             /**
188                 The address returned is aligned by \p nAlign boundary.
189                 \p nAlign parameter should be power of 2.
190
191                 The function guarantees alignment for first element of array only.
192             */
193             pointer allocate(size_type nAlign, size_type nCount, const void *)
194             {
195                 return ( allocate( nAlign, nCount ));
196             }
197
198             /// construct object at \p ptr with value \p val
199             void construct(pointer ptr, const T& val)
200             {
201                 prototype a;
202                 a.construct( ptr, val );
203             }
204
205             /// destroy object at \p ptr
206             void destroy(pointer ptr)
207             {
208                 prototype a;
209                 a.destroy( ptr );
210             }
211
212             /// estimate maximum array size
213             size_type max_size() const CDS_NOEXCEPT
214             {
215                 prototype a;
216                 return a.max_size();
217             }
218         };
219     }   // namespace OS
220 }  // namespace cds
221
222 #endif  // #ifndef CDSLIB_OS_ALLOC_ALIGNED_H