Replaced deprecated throw() function specifier with noexcept
[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
58 namespace cds {
59     /// OS specific wrappers
60     /**
61         This namespace contains OS-specific implementations.
62         Usually, the sub-namespaces contain OS-specific wrappers for a feature.
63
64         Typical usage pattern:
65         \code
66             namespace cds {
67             namespace OS {
68                 namespace Linux {
69                     class Feature {
70                         // ...
71                     };
72                 }
73
74                 // import Linux::Feature class into cds::OS namespace
75                 using Linux::Feature;
76                 // now, cds::OS::Feature refers to cds::OS::Linux::Feature
77             }
78             }
79         \endcode
80     */
81     namespace OS {
82         /// Aligned allocator
83         /**
84             This allocator is intended for allocating of an aligned memory block. It uses wrappers around platform-specific
85             function for allocating and deallocating the block of memory:
86             \li \p aligned_malloc for allocating
87             \li \p aligned_free for deallocating
88
89             The \p aligned_malloc function wraps:
90             \li \p for Win: \p _aligned_malloc function
91             \li \p for other OSes: \p posix_memalign / \p memalign function
92
93             The \p aligned_free function wraps:
94             \li \p for Win: \p _aligned_free function
95             \li \p for other OSes: \p free function
96
97             This class should not be used directly. Use cds::details::AlignedAllocator instead.
98         */
99         template <typename T>
100         class aligned_allocator
101         {
102             typedef std::allocator<T>  prototype    ;   ///< prototype (the source of typedefs)
103         public:
104             typedef typename prototype::value_type       value_type      ;  ///< value type
105             typedef typename prototype::pointer          pointer         ;  ///< pointer to value type
106             typedef typename prototype::reference        reference       ;  ///< value reference type
107             typedef typename prototype::const_pointer    const_pointer   ;  ///< const pointer to value type
108             typedef typename prototype::const_reference  const_reference ;  ///< const value reference type
109
110             typedef typename prototype::size_type        size_type       ;  ///< size type
111             typedef typename prototype::difference_type  difference_type ;  ///< difference type
112
113             /// convert an aligned_allocator<T> to an aligned_allocator<OTHER>
114             template<class OTHER>
115             struct rebind
116             {
117                 typedef aligned_allocator<OTHER> other; ///< Rebinding result
118             };
119
120         public:
121             /// return address of mutable \p v
122             pointer address(reference v) const
123             {
124                 prototype a;
125                 return a.address( v );
126             }
127
128             /// return address of nonmutable \p v
129             const_pointer address(const_reference v) const
130             {
131                 prototype a;
132                 return a.address( v );
133             }
134
135             // construct default allocator (do nothing)
136             aligned_allocator() CDS_NOEXCEPT
137             {}
138
139             /// construct by copying (do nothing)
140             aligned_allocator(const aligned_allocator<T>&) CDS_NOEXCEPT
141             {}
142
143             /// construct from a related allocator (do nothing)
144             template <class OTHER>
145             aligned_allocator(const aligned_allocator<OTHER>&) CDS_NOEXCEPT
146             {}
147
148             /// assign from a related allocator (do nothing)
149             template <class OTHER>
150             aligned_allocator<T>& operator=(const aligned_allocator<OTHER>&)
151             {
152                 return (*this);
153             }
154
155             /// deallocate object at \p ptr, ignore size
156             void deallocate(pointer ptr, size_type)
157             {
158                 cds::OS::aligned_free( ptr );
159             }
160
161             /// allocate array of \p nCount elements
162             /**
163                 The address returned is aligned by \p nAlign boundary.
164                 \p nAlign parameter should be power of 2.
165
166                 The function guarantees the alignment for first element of array only.
167                 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:
168                 \code
169                 sizeof(T) % nAlign == 0
170                 \endcode
171
172                 The function, like operator \p new does not return \p nullptr.
173                 In no memory situation the function throws \p std::bad_alloc exception.
174             */
175             pointer allocate( size_type nAlign, size_type nCount )
176             {
177                 assert( cds::beans::is_power2( nAlign ));
178                 pointer p = reinterpret_cast<T *>( cds::OS::aligned_malloc( sizeof(T) * nCount, nAlign ));
179                 if ( !p )
180                     throw std::bad_alloc();
181                 assert( cds::details::is_aligned( p, nAlign ));
182                 return p;
183             }
184
185             /// allocate array of \p nCount elements, ignore hint
186             /**
187                 The address returned is aligned by \p nAlign boundary.
188                 \p nAlign parameter should be power of 2.
189
190                 The function guarantees alignment for first element of array only.
191             */
192             pointer allocate(size_type nAlign, size_type nCount, const void *)
193             {
194                 return ( allocate( nAlign, nCount ));
195             }
196
197             /// construct object at \p ptr with value \p val
198             void construct(pointer ptr, const T& val)
199             {
200                 prototype a;
201                 a.construct( ptr, val );
202             }
203
204             /// destroy object at \p ptr
205             void destroy(pointer ptr)
206             {
207                 prototype a;
208                 a.destroy( ptr );
209             }
210
211             /// estimate maximum array size
212             size_type max_size() const CDS_NOEXCEPT
213             {
214                 prototype a;
215                 return a.max_size();
216             }
217         };
218     }   // namespace OS
219 }  // namespace cds
220
221 #endif  // #ifndef CDSLIB_OS_ALLOC_ALIGNED_H