You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

452 lines
13 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: stlsoft/containers/util/array_policies.hpp
  3. *
  4. * Purpose: Contains the construction policies for the array (fixed and
  5. * frame) classes.
  6. *
  7. * Created: 1st September 2002
  8. * Updated: 10th August 2009
  9. *
  10. * Thanks to: Neal Becker for suggesting the uninitialised mode.
  11. *
  12. * Home: http://stlsoft.org/
  13. *
  14. * Copyright (c) 2002-2009, Matthew Wilson and Synesis Software
  15. * All rights reserved.
  16. *
  17. * Redistribution and use in source and binary forms, with or without
  18. * modification, are permitted provided that the following conditions are met:
  19. *
  20. * - Redistributions of source code must retain the above copyright notice, this
  21. * list of conditions and the following disclaimer.
  22. * - Redistributions in binary form must reproduce the above copyright notice,
  23. * this list of conditions and the following disclaimer in the documentation
  24. * and/or other materials provided with the distribution.
  25. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  26. * any contributors may be used to endorse or promote products derived from
  27. * this software without specific prior written permission.
  28. *
  29. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  30. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  31. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  32. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  33. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  34. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  35. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  36. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  37. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  38. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  39. * POSSIBILITY OF SUCH DAMAGE.
  40. *
  41. * ////////////////////////////////////////////////////////////////////// */
  42. /** \file stlsoft/containers/util/array_policies.hpp
  43. *
  44. * \brief [C++ only] Definition of the stlsoft::do_construction,
  45. * stlsoft::do_construction_always, stlsoft::do_construction_never and
  46. * stlsoft::do_initialisation_never construction policy classes for
  47. * the multidimensional arrays
  48. * (\ref group__library__containers "Containers" Library).
  49. */
  50. #ifndef STLSOFT_INCL_STLSOFT_CONTAINERS_UTIL_HPP_ARRAY_POLICIES
  51. #define STLSOFT_INCL_STLSOFT_CONTAINERS_UTIL_HPP_ARRAY_POLICIES
  52. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  53. # define STLSOFT_VER_STLSOFT_CONTAINERS_UTIL_HPP_ARRAY_POLICIES_MAJOR 5
  54. # define STLSOFT_VER_STLSOFT_CONTAINERS_UTIL_HPP_ARRAY_POLICIES_MINOR 1
  55. # define STLSOFT_VER_STLSOFT_CONTAINERS_UTIL_HPP_ARRAY_POLICIES_REVISION 4
  56. # define STLSOFT_VER_STLSOFT_CONTAINERS_UTIL_HPP_ARRAY_POLICIES_EDIT 136
  57. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  58. /* /////////////////////////////////////////////////////////////////////////
  59. * Compatibility
  60. */
  61. /*
  62. [DocumentationStatus:Ready]
  63. */
  64. /* /////////////////////////////////////////////////////////////////////////
  65. * Includes
  66. */
  67. #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
  68. # include <stlsoft/stlsoft.h>
  69. #endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */
  70. #ifndef STLSOFT_INCL_STLSOFT_META_HPP_N_TYPES
  71. # include <stlsoft/meta/n_types.hpp>
  72. #endif /* !STLSOFT_INCL_STLSOFT_META_HPP_N_TYPES */
  73. #ifndef STLSOFT_INCL_H_STRING
  74. # define STLSOFT_INCL_H_STRING
  75. # include <string.h> // for memcpy(), memset()
  76. #endif /* !STLSOFT_INCL_H_STRING */
  77. /* /////////////////////////////////////////////////////////////////////////
  78. * Namespace
  79. */
  80. #ifndef _STLSOFT_NO_NAMESPACE
  81. namespace stlsoft
  82. {
  83. #endif /* _STLSOFT_NO_NAMESPACE */
  84. /* /////////////////////////////////////////////////////////////////////////
  85. * Compiler
  86. */
  87. #ifdef STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO
  88. # undef STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO
  89. #endif /* STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO */
  90. #if defined(STLSOFT_COMPILER_IS_GCC) && \
  91. __GNUC__ < 4
  92. # define STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO
  93. #endif /* compiler */
  94. /* /////////////////////////////////////////////////////////////////////////
  95. * Construction policy classes
  96. */
  97. /** \brief Traits class that controls whether elements in STLSoft arrays are in-place constructed and destroyed
  98. *
  99. * \ingroup group__library__containers
  100. *
  101. * \param T The type
  102. *
  103. * The template's value is <b>true</b>, indicating that construction and
  104. * destruction will be performed, but is <b>false</b> for the specialisations
  105. * for integral and boolean types, indicating that no initialisation of
  106. * the array elements will be performed.
  107. *
  108. * You would customise as follows:
  109. \code
  110. struct YourPodType
  111. {
  112. int x;
  113. int y;
  114. int z;
  115. };
  116. namespace stlsoft
  117. {
  118. template <>
  119. struct do_construction<YourPodType>
  120. {
  121. enum { value = false }; // This will cause the array elements to not be initialised
  122. }
  123. }
  124. // Create a 2x3 2-dimensional array of YourPodType
  125. stlsoft::fixed_array_2d<YourPodType> pods(2, 3);
  126. \endcode
  127. *
  128. * \see stlsoft::fixed_array_1d |
  129. * stlsoft::fixed_array_2d |
  130. * stlsoft::fixed_array_3d |
  131. * stlsoft::fixed_array_4d |
  132. * stlsoft::static_array_1d |
  133. * stlsoft::static_array_2d |
  134. * stlsoft::static_array_3d |
  135. * stlsoft::static_array_4d
  136. */
  137. template <ss_typename_param_k T>
  138. struct do_construction
  139. {
  140. enum
  141. {
  142. value = true //!< If \c true the array elements are constructed, otherwise they are not
  143. };
  144. typedef one_type type;
  145. };
  146. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  147. STLSOFT_TEMPLATE_SPECIALISATION
  148. struct do_construction<ss_sint8_t> { enum { value = false }; typedef two_type type; };
  149. STLSOFT_TEMPLATE_SPECIALISATION
  150. struct do_construction<ss_uint8_t> { enum { value = false }; typedef two_type type; };
  151. STLSOFT_TEMPLATE_SPECIALISATION
  152. struct do_construction<ss_sint16_t> { enum { value = false }; typedef two_type type; };
  153. STLSOFT_TEMPLATE_SPECIALISATION
  154. struct do_construction<ss_uint16_t> { enum { value = false }; typedef two_type type; };
  155. STLSOFT_TEMPLATE_SPECIALISATION
  156. struct do_construction<ss_sint32_t> { enum { value = false }; typedef two_type type; };
  157. STLSOFT_TEMPLATE_SPECIALISATION
  158. struct do_construction<ss_uint32_t> { enum { value = false }; typedef two_type type; };
  159. #ifdef STLSOFT_CF_64BIT_INT_SUPPORT
  160. STLSOFT_TEMPLATE_SPECIALISATION
  161. struct do_construction<ss_sint64_t> { enum { value = false }; typedef two_type type; };
  162. STLSOFT_TEMPLATE_SPECIALISATION
  163. struct do_construction<ss_uint64_t> { enum { value = false }; typedef two_type type; };
  164. #endif /* STLSOFT_CF_64BIT_INT_SUPPORT */
  165. STLSOFT_TEMPLATE_SPECIALISATION
  166. struct do_construction<float> { enum { value = false }; typedef two_type type; };
  167. STLSOFT_TEMPLATE_SPECIALISATION
  168. struct do_construction<double> { enum { value = false }; typedef two_type type; };
  169. STLSOFT_TEMPLATE_SPECIALISATION
  170. struct do_construction<long double> { enum { value = false }; typedef two_type type; };
  171. #ifdef STLSOFT_CF_NATIVE_BOOL_SUPPORT
  172. STLSOFT_TEMPLATE_SPECIALISATION
  173. struct do_construction<ss_bool_t> { enum { value = false }; typedef two_type type; };
  174. #endif /* STLSOFT_CF_NATIVE_BOOL_SUPPORT */
  175. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  176. /** \brief Stipulates that array elements are always constructed
  177. *
  178. * \ingroup group__library__containers
  179. *
  180. * \see stlsoft::do_construction
  181. */
  182. struct do_construction_always
  183. {
  184. enum { value = true };
  185. typedef one_type type;
  186. };
  187. /** \brief Stipulates that array elements are never constructed
  188. *
  189. * \ingroup group__library__containers
  190. *
  191. * \see stlsoft::do_construction
  192. */
  193. struct do_construction_never
  194. {
  195. enum { value = false };
  196. typedef two_type type;
  197. };
  198. /** \brief Stipulates that array elements are never initialised in any way
  199. *
  200. * \ingroup group__library__containers
  201. *
  202. * \see stlsoft::do_construction
  203. */
  204. struct do_initialisation_never
  205. {
  206. enum { value = false };
  207. typedef three_type type;
  208. };
  209. /* /////////////////////////////////////////////////////////////////////////
  210. * Helper functions
  211. */
  212. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  213. template< ss_typename_param_k T
  214. , ss_typename_param_k A
  215. >
  216. void do_construct_1(A& ator, T *p, ss_size_t n, one_type)
  217. {
  218. for(T *e = p + n; p != e; ++p)
  219. {
  220. ator.construct(p, T());
  221. }
  222. }
  223. template< ss_typename_param_k T
  224. , ss_typename_param_k A
  225. >
  226. void do_construct_1(A& /* ator */, T *p, ss_size_t n, two_type)
  227. {
  228. #if 1
  229. ::memset(p, 0, n * sizeof(T));
  230. #else /* ? 0 */
  231. stlsoft_ns_qual_std(fill_n)(p, n, 0);
  232. #endif /* 0 */
  233. }
  234. template< ss_typename_param_k T
  235. , ss_typename_param_k A
  236. >
  237. void do_construct_1(A& /* ator */, T * /* p */, ss_size_t /* n */, three_type)
  238. {}
  239. template< ss_typename_param_k T
  240. , ss_typename_param_k A
  241. >
  242. void do_construct_2(A& ator, T *p, ss_size_t n, T const& value, one_type)
  243. {
  244. #if 0
  245. std::uninitialized_fill_n(p, n, value);
  246. #else /* ? 0 */
  247. for(T *e = p + n; p != e; ++p)
  248. {
  249. ator.construct(p, value);
  250. }
  251. #endif /* 0 */
  252. }
  253. template< ss_typename_param_k T
  254. , ss_typename_param_k A
  255. >
  256. void do_construct_2(A& /* ator */, T* p, ss_size_t n, T const& value, two_type)
  257. {
  258. for(T* e = p + n; p != e; ++p)
  259. {
  260. ::memcpy(p, &value, sizeof(T));
  261. }
  262. }
  263. template< ss_typename_param_k T
  264. , ss_typename_param_k A
  265. >
  266. void do_construct_2(A& /* ator */, T* /* p */, ss_size_t /* n */, T const& value, three_type)
  267. {}
  268. template< ss_typename_param_k T
  269. , ss_typename_param_k A
  270. >
  271. void do_copy_construct_1(A& ator, T* p, T const* src, ss_size_t n, one_type)
  272. {
  273. for(T* e = p + n; p != e; ++p, ++src)
  274. {
  275. ator.construct(p, *src);
  276. }
  277. }
  278. template< ss_typename_param_k T
  279. , ss_typename_param_k A
  280. >
  281. void do_copy_construct_1(A& /* ator */, T* p, T const* src, ss_size_t n, two_type)
  282. {
  283. for(T* e = p + n; p != e; ++p, ++src)
  284. {
  285. ::memcpy(p, src, sizeof(T));
  286. }
  287. }
  288. template< ss_typename_param_k T
  289. , ss_typename_param_k A
  290. >
  291. void do_copy_construct_1(A& /* ator */, T* /* p */, T const* /* src */, ss_size_t /* n */, three_type)
  292. {}
  293. template< ss_typename_param_k T
  294. , ss_typename_param_k A
  295. >
  296. void do_destroy_1(A& ator, T* p, ss_size_t n, one_type)
  297. {
  298. for(T* e = p + n; p != e; ++p)
  299. {
  300. ator.destroy(p);
  301. }
  302. }
  303. template< ss_typename_param_k T
  304. , ss_typename_param_k A
  305. >
  306. void do_destroy_1(A& /* ator */, T* /* p */, ss_size_t /* n */, two_type)
  307. {}
  308. template< ss_typename_param_k T
  309. , ss_typename_param_k A
  310. >
  311. void do_destroy_1(A& /* ator */, T* /* p */, ss_size_t /* n */, three_type)
  312. {}
  313. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  314. /* /////////////////////////////////////////////////////////////////////////
  315. * Helper classes
  316. */
  317. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  318. template< ss_typename_param_k T
  319. , ss_typename_param_k A
  320. , ss_typename_param_k P
  321. >
  322. struct array_range_initialiser
  323. {
  324. public:
  325. typedef T value_type;
  326. typedef T* pointer;
  327. typedef T const* const_pointer;
  328. typedef A allocator_type;
  329. typedef P initialisation_policy_type;
  330. private:
  331. # if defined(STLSOFT_COMPILER_IS_MSVC) && \
  332. _MSC_VER < 1310
  333. typedef initialisation_policy_type::type selector_type;
  334. # else /* ? compiler */
  335. typedef ss_typename_type_k initialisation_policy_type::type selector_type;
  336. # endif /* compiler */
  337. public:
  338. /// \brief Performs in-place default construction of n elements, whose first element
  339. /// is located at p
  340. ///
  341. /// \note If the initialisation policy is 'true', then the value_type is assumed to be
  342. /// of non-POD type, and therefore constructed. If 'false', then the value_type is
  343. /// assumed to be POD and the memory is zero-filled (via memset())
  344. static void construct(allocator_type& ator, pointer p, ss_size_t n)
  345. {
  346. do_construct_1(ator, p, n, selector_type());
  347. }
  348. /// \brief Performs in-place copy construction of n elements, whose first element
  349. /// is located at p, where *(p + n) is set to *(src + n)
  350. static void copy_construct(allocator_type& ator, pointer p, const_pointer src, ss_size_t n)
  351. {
  352. do_copy_construct_1(ator, p, src, n, selector_type());
  353. }
  354. /// \brief Performs in-place copy construction of n elements, whose first element
  355. /// is located at p, where each element == val
  356. static void construct(allocator_type& ator, pointer p, ss_size_t n, value_type const& val)
  357. {
  358. do_construct_2(ator, p, n, val, selector_type());
  359. }
  360. static void destroy(allocator_type& ator, pointer p, ss_size_t n)
  361. {
  362. do_destroy_1(ator, p, n, selector_type());
  363. }
  364. };
  365. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  366. /* ////////////////////////////////////////////////////////////////////// */
  367. #ifndef _STLSOFT_NO_NAMESPACE
  368. } // namespace stlsoft
  369. #endif /* _STLSOFT_NO_NAMESPACE */
  370. /* ////////////////////////////////////////////////////////////////////// */
  371. #endif /* !STLSOFT_INCL_STLSOFT_CONTAINERS_UTIL_HPP_ARRAY_POLICIES */
  372. /* ///////////////////////////// end of file //////////////////////////// */