1 //----------------------------------------------------------------------------
2 /// @file algorithm.hpp
3 /// @brief low level functions of create, destroy, move and merge functions
4 ///
5 /// @author Copyright (c) 2017 Francisco Jose Tapia (fjtapia@gmail.com )\n
6 /// Distributed under the Boost Software License, Version 1.0.\n
7 /// ( See accompanying file LICENSE_1_0.txt or copy at
8 /// http://www.boost.org/LICENSE_1_0.txt )
9 /// @version 0.1
10 ///
11 /// @remarks
12 //-----------------------------------------------------------------------------
13 #ifndef __BOOST_SORT_COMMON_UTIL_ALGORITHM_HPP
14 #define __BOOST_SORT_COMMON_UTIL_ALGORITHM_HPP
15
16 #include <algorithm>
17 #include <functional>
18 #include <iterator>
19 #include <memory>
20 #include <type_traits>
21 #include <vector>
22 #include <boost/sort/common/util/traits.hpp>
23
24 namespace boost
25 {
26 namespace sort
27 {
28 namespace common
29 {
30 namespace util
31 {
32 //
33 //###########################################################################
34 //
35 // I M P O R T A N T
36 //
37 // The functions of this file are for internal use only
38 // All the operations are done with move operations, because the copy
39 // operations are unnecesary
40 //
41 //###########################################################################
42 //
43 //----------------------------------------------------------------------------
44 //
45 // F U N C T I O N S I N T H E F I L E
46 //
47 //----------------------------------------------------------------------------
48 //
49 // static inline uint32_t nbits32 (uint32_t num) noexcept
50 //
51 // static inline uint32_t nbits64 (uint64_t num)
52 //
53 // template < class Value_t, class... Args >
54 // inline void construct_object (Value_t *ptr, Args &&... args)
55 //
56 // template < class Value_t >
57 // inline void destroy_object (Value_t *ptr)
58 //
59 // template < class Iter_t, class Value_t = value_iter<Iter_t> >
60 // void initialize (Iter_t first, Iter_t last, Value_t && val)
61 //
62 // template < class Iter1_t, class Iter2_t >
63 // Iter2_t move_forward (Iter2_t it_dest, Iter1_t first, Iter1_t last)
64 //
65 // template < class Iter1_t, class Iter2_t >
66 // Iter2_t move_backward (Iter2_t it_dest, Iter1_t first, Iter1_t last)
67 //
68 // template < class Iter_t, class Value_t = value_iter< Iter_t > >
69 // Value_t * move_construct (Value_t *ptr, Iter_t first, Iter_t last)
70 //
71 // template < class Iter_t >
72 // void destroy (Iter_t first, const Iter_t last)
73 //
74 // template < class Iter_t >
75 // void reverse (Iter_t first, const Iter_t last)
76 //
77 //----------------------------------------------------------------------------
78 //
79 //--------------------------------------------------------------------------
80 //
81 // G L O B A L V A R I B L E S
82 //
83 //--------------------------------------------------------------------------
84 //
85 // this array represent the number of bits needed for to represent the
86 // first 256 numbers
87 static constexpr const uint32_t tmsb[256] =
88 { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
89 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
90 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7,
91 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
92 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
93 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8,
94 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
95 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
96 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
97 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
98 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
99 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 };
100 //
101 //---------------------------------------------------------------------------
102 //
103 // F U N C T I O N S
104 //
105 //---------------------------------------------------------------------------
106 //
107 //---------------------------------------------------------------------------
108 // function : nbits32
109 /// @brief Obtain the number of bits of a number equal or greater than num
110 /// @param num : Number to examine
111 /// @return Number of bits
112 //---------------------------------------------------------------------------
nbits32(uint32_t num)113 static inline uint32_t nbits32 (uint32_t num) noexcept
114 {
115 int Pos = (num & 0xffff0000U) ? 16 : 0;
116 if ((num >> Pos) & 0xff00U) Pos += 8;
117 return (tmsb[num >> Pos] + Pos);
118 }
119 //
120 //---------------------------------------------------------------------------
121 // function : nbits64
122 /// @brief Obtain the number of bits of a number equal or greater than num
123 /// @param num : Number to examine
124 /// @exception none
125 /// @return Number of bits
126 //---------------------------------------------------------------------------
nbits64(uint64_t num)127 static inline uint32_t nbits64(uint64_t num)noexcept
128 {
129 uint32_t Pos = (num & 0xffffffff00000000ULL) ? 32 : 0;
130 if ((num >> Pos) & 0xffff0000ULL) Pos += 16;
131 if ((num >> Pos) & 0xff00ULL) Pos += 8;
132 return (tmsb[num >> Pos] + Pos);
133 }
134 //
135 //-----------------------------------------------------------------------------
136 // function : construct_object
137 /// @brief create an object in the memory specified by ptr
138 ///
139 /// @param ptr : pointer to the memory where to create the object
140 /// @param args : arguments to the constructor
141 //-----------------------------------------------------------------------------
142 template <class Value_t, class ... Args>
construct_object(Value_t * ptr,Args &&...args)143 inline void construct_object (Value_t *ptr, Args &&... args)
144 {
145 (::new (static_cast<void *>(ptr)) Value_t(std::forward< Args > (args)...));
146 };
147 //
148 //-----------------------------------------------------------------------------
149 // function : destroy_object
150 /// @brief destroy an object in the memory specified by ptr
151 /// @param ptr : pointer to the object to destroy
152 //-----------------------------------------------------------------------------
153 template<class Value_t>
destroy_object(Value_t * ptr)154 inline void destroy_object(Value_t *ptr)
155 {
156 ptr->~Value_t();
157 };
158 //
159 //-----------------------------------------------------------------------------
160 // function : initialize
161 /// @brief initialize a range of objects with the object val moving across them
162 ///
163 /// @param first : itertor to the first element to initialize
164 /// @param last : iterator to the last element to initialize
165 /// @param val : object used for the initialization
166 //-----------------------------------------------------------------------------
167 template <class Iter_t, class Value_t = value_iter<Iter_t> >
initialize(Iter_t first,Iter_t last,Value_t & val)168 inline void initialize (Iter_t first, Iter_t last, Value_t & val)
169 {
170 //------------------------------------------------------------------------
171 // Metaprogramming
172 //------------------------------------------------------------------------
173 typedef value_iter<Iter_t> value_t;
174 static_assert (std::is_same< Value_t, value_t >::value,
175 "Incompatible iterators\n");
176
177 //------------------------------------------------------------------------
178 // Code
179 //------------------------------------------------------------------------
180 if (first == last) return;
181 construct_object(&(*first), std::move(val));
182
183 Iter_t it1 = first, it2 = first + 1;
184 while (it2 != last)
185 {
186 construct_object(&(*(it2++)), std::move(*(it1++)));
187 };
188 val = std::move(*(last - 1));
189 };
190 //
191 //-----------------------------------------------------------------------------
192 // function : move_forward
193 /// @brief Move initialized objets
194 /// @param it_dest : iterator to the final place of the objects
195 /// @param first : iterator to the first element to move
196 /// @param last : iterator to the last element to move
197 /// @return Output iterator to the element past the last element
198 /// moved (it_dest + (last - first))
199 //-----------------------------------------------------------------------------
200 template <class Iter1_t, class Iter2_t>
move_forward(Iter2_t it_dest,Iter1_t first,Iter1_t last)201 inline Iter2_t move_forward (Iter2_t it_dest, Iter1_t first, Iter1_t last)
202 {
203 //------------------------------------------------------------------------
204 // Metaprogramming
205 //------------------------------------------------------------------------
206 typedef value_iter<Iter1_t> value1_t;
207 typedef value_iter<Iter2_t> value2_t;
208 static_assert (std::is_same< value1_t, value2_t >::value,
209 "Incompatible iterators\n");
210
211 //------------------------------------------------------------------------
212 // Code
213 //------------------------------------------------------------------------
214 while (first != last)
215 { *it_dest++ = std::move(*first++);
216 }
217 return it_dest;
218
219 };
220 //
221 //-----------------------------------------------------------------------------
222 // function : move_backard
223 /// @brief Move initialized objets in reverse order
224 /// @param it_dest : last iterator to the final place of the objects
225 /// @param first : iterator to the first element to move
226 /// @param last : iterator to the last element to move
227 //-----------------------------------------------------------------------------
228 template<class Iter1_t, class Iter2_t>
move_backward(Iter2_t it_dest,Iter1_t first,Iter1_t last)229 inline Iter2_t move_backward(Iter2_t it_dest, Iter1_t first, Iter1_t last)
230 {
231 //------------------------------------------------------------------------
232 // Metaprogramming
233 //------------------------------------------------------------------------
234 typedef value_iter<Iter1_t> value1_t;
235 typedef value_iter<Iter2_t> value2_t;
236 static_assert (std::is_same< value1_t, value2_t >::value,
237 "Incompatible iterators\n");
238
239 //------------------------------------------------------------------------
240 // Code
241 //------------------------------------------------------------------------
242 while (first != last)
243 { *(--it_dest) = std::move (*(--last));
244 }
245 return it_dest;
246 };
247
248 //
249 //-----------------------------------------------------------------------------
250 // function : move_construct
251 /// @brief Move objets to uninitialized memory
252 ///
253 /// @param ptr : pointer to the memory where to create the objects
254 /// @param first : iterator to the first element to move
255 /// @param last : iterator to the last element to move
256 //-----------------------------------------------------------------------------
257 template<class Iter_t, class Value_t = value_iter<Iter_t> >
move_construct(Value_t * ptr,Iter_t first,Iter_t last)258 inline Value_t * move_construct(Value_t *ptr, Iter_t first, Iter_t last)
259 {
260 //------------------------------------------------------------------------
261 // Metaprogramming
262 //------------------------------------------------------------------------
263 typedef typename iterator_traits<Iter_t>::value_type value2_t;
264 static_assert (std::is_same< Value_t, value2_t >::value,
265 "Incompatible iterators\n");
266
267 //------------------------------------------------------------------------
268 // Code
269 //------------------------------------------------------------------------
270 while (first != last)
271 {
272 ::new (static_cast<void *>(ptr++)) Value_t(std::move(*(first++)));
273 };
274 return ptr;
275 };
276 //
277 //-----------------------------------------------------------------------------
278 // function : destroy
279 /// @brief destroy the elements between first and last
280 /// @param first : iterator to the first element to destroy
281 /// @param last : iterator to the last element to destroy
282 //-----------------------------------------------------------------------------
283 template<class Iter_t>
destroy(Iter_t first,const Iter_t last)284 inline void destroy(Iter_t first, const Iter_t last)
285 {
286 while (first != last)
287 destroy_object(&(*(first++)));
288 };
289 //
290 //-----------------------------------------------------------------------------
291 // function : reverse
292 /// @brief destroy the elements between first and last
293 /// @param first : iterator to the first element to destroy
294 /// @param last : iterator to the last element to destroy
295 //-----------------------------------------------------------------------------
296 template<class Iter_t>
reverse(Iter_t first,Iter_t last)297 inline void reverse(Iter_t first, Iter_t last)
298 {
299 std::reverse ( first, last);
300 };
301 //
302 //****************************************************************************
303 };// End namespace util
304 };// End namespace common
305 };// End namespace sort
306 };// End namespace boost
307 //****************************************************************************
308 //
309 #endif
310