algorithm.hpp 12 KB

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