algorithm.hpp 12 KB

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