/* ///////////////////////////////////////////////////////////////////////// * File: stlsoft/containers/util/array_policies.hpp * * Purpose: Contains the construction policies for the array (fixed and * frame) classes. * * Created: 1st September 2002 * Updated: 10th August 2009 * * Thanks to: Neal Becker for suggesting the uninitialised mode. * * Home: http://stlsoft.org/ * * Copyright (c) 2002-2009, Matthew Wilson and Synesis Software * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of * any contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * ////////////////////////////////////////////////////////////////////// */ /** \file stlsoft/containers/util/array_policies.hpp * * \brief [C++ only] Definition of the stlsoft::do_construction, * stlsoft::do_construction_always, stlsoft::do_construction_never and * stlsoft::do_initialisation_never construction policy classes for * the multidimensional arrays * (\ref group__library__containers "Containers" Library). */ #ifndef STLSOFT_INCL_STLSOFT_CONTAINERS_UTIL_HPP_ARRAY_POLICIES #define STLSOFT_INCL_STLSOFT_CONTAINERS_UTIL_HPP_ARRAY_POLICIES #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION # define STLSOFT_VER_STLSOFT_CONTAINERS_UTIL_HPP_ARRAY_POLICIES_MAJOR 5 # define STLSOFT_VER_STLSOFT_CONTAINERS_UTIL_HPP_ARRAY_POLICIES_MINOR 1 # define STLSOFT_VER_STLSOFT_CONTAINERS_UTIL_HPP_ARRAY_POLICIES_REVISION 4 # define STLSOFT_VER_STLSOFT_CONTAINERS_UTIL_HPP_ARRAY_POLICIES_EDIT 136 #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */ /* ///////////////////////////////////////////////////////////////////////// * Compatibility */ /* [DocumentationStatus:Ready] */ /* ///////////////////////////////////////////////////////////////////////// * Includes */ #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT # include #endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */ #ifndef STLSOFT_INCL_STLSOFT_META_HPP_N_TYPES # include #endif /* !STLSOFT_INCL_STLSOFT_META_HPP_N_TYPES */ #ifndef STLSOFT_INCL_H_STRING # define STLSOFT_INCL_H_STRING # include // for memcpy(), memset() #endif /* !STLSOFT_INCL_H_STRING */ /* ///////////////////////////////////////////////////////////////////////// * Namespace */ #ifndef _STLSOFT_NO_NAMESPACE namespace stlsoft { #endif /* _STLSOFT_NO_NAMESPACE */ /* ///////////////////////////////////////////////////////////////////////// * Compiler */ #ifdef STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO # undef STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO #endif /* STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO */ #if defined(STLSOFT_COMPILER_IS_GCC) && \ __GNUC__ < 4 # define STLSOFT_MULTIDIM_ARRAY_FEATURE_REQUIRES_COPY_CTOR_WITH_RVO #endif /* compiler */ /* ///////////////////////////////////////////////////////////////////////// * Construction policy classes */ /** \brief Traits class that controls whether elements in STLSoft arrays are in-place constructed and destroyed * * \ingroup group__library__containers * * \param T The type * * The template's value is true, indicating that construction and * destruction will be performed, but is false for the specialisations * for integral and boolean types, indicating that no initialisation of * the array elements will be performed. * * You would customise as follows: \code struct YourPodType { int x; int y; int z; }; namespace stlsoft { template <> struct do_construction { enum { value = false }; // This will cause the array elements to not be initialised } } // Create a 2x3 2-dimensional array of YourPodType stlsoft::fixed_array_2d pods(2, 3); \endcode * * \see stlsoft::fixed_array_1d | * stlsoft::fixed_array_2d | * stlsoft::fixed_array_3d | * stlsoft::fixed_array_4d | * stlsoft::static_array_1d | * stlsoft::static_array_2d | * stlsoft::static_array_3d | * stlsoft::static_array_4d */ template struct do_construction { enum { value = true //!< If \c true the array elements are constructed, otherwise they are not }; typedef one_type type; }; #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION STLSOFT_TEMPLATE_SPECIALISATION struct do_construction { enum { value = false }; typedef two_type type; }; STLSOFT_TEMPLATE_SPECIALISATION struct do_construction { enum { value = false }; typedef two_type type; }; STLSOFT_TEMPLATE_SPECIALISATION struct do_construction { enum { value = false }; typedef two_type type; }; STLSOFT_TEMPLATE_SPECIALISATION struct do_construction { enum { value = false }; typedef two_type type; }; STLSOFT_TEMPLATE_SPECIALISATION struct do_construction { enum { value = false }; typedef two_type type; }; STLSOFT_TEMPLATE_SPECIALISATION struct do_construction { enum { value = false }; typedef two_type type; }; #ifdef STLSOFT_CF_64BIT_INT_SUPPORT STLSOFT_TEMPLATE_SPECIALISATION struct do_construction { enum { value = false }; typedef two_type type; }; STLSOFT_TEMPLATE_SPECIALISATION struct do_construction { enum { value = false }; typedef two_type type; }; #endif /* STLSOFT_CF_64BIT_INT_SUPPORT */ STLSOFT_TEMPLATE_SPECIALISATION struct do_construction { enum { value = false }; typedef two_type type; }; STLSOFT_TEMPLATE_SPECIALISATION struct do_construction { enum { value = false }; typedef two_type type; }; STLSOFT_TEMPLATE_SPECIALISATION struct do_construction { enum { value = false }; typedef two_type type; }; #ifdef STLSOFT_CF_NATIVE_BOOL_SUPPORT STLSOFT_TEMPLATE_SPECIALISATION struct do_construction { enum { value = false }; typedef two_type type; }; #endif /* STLSOFT_CF_NATIVE_BOOL_SUPPORT */ #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */ /** \brief Stipulates that array elements are always constructed * * \ingroup group__library__containers * * \see stlsoft::do_construction */ struct do_construction_always { enum { value = true }; typedef one_type type; }; /** \brief Stipulates that array elements are never constructed * * \ingroup group__library__containers * * \see stlsoft::do_construction */ struct do_construction_never { enum { value = false }; typedef two_type type; }; /** \brief Stipulates that array elements are never initialised in any way * * \ingroup group__library__containers * * \see stlsoft::do_construction */ struct do_initialisation_never { enum { value = false }; typedef three_type type; }; /* ///////////////////////////////////////////////////////////////////////// * Helper functions */ #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION template< ss_typename_param_k T , ss_typename_param_k A > void do_construct_1(A& ator, T *p, ss_size_t n, one_type) { for(T *e = p + n; p != e; ++p) { ator.construct(p, T()); } } template< ss_typename_param_k T , ss_typename_param_k A > void do_construct_1(A& /* ator */, T *p, ss_size_t n, two_type) { #if 1 ::memset(p, 0, n * sizeof(T)); #else /* ? 0 */ stlsoft_ns_qual_std(fill_n)(p, n, 0); #endif /* 0 */ } template< ss_typename_param_k T , ss_typename_param_k A > void do_construct_1(A& /* ator */, T * /* p */, ss_size_t /* n */, three_type) {} template< ss_typename_param_k T , ss_typename_param_k A > void do_construct_2(A& ator, T *p, ss_size_t n, T const& value, one_type) { #if 0 std::uninitialized_fill_n(p, n, value); #else /* ? 0 */ for(T *e = p + n; p != e; ++p) { ator.construct(p, value); } #endif /* 0 */ } template< ss_typename_param_k T , ss_typename_param_k A > void do_construct_2(A& /* ator */, T* p, ss_size_t n, T const& value, two_type) { for(T* e = p + n; p != e; ++p) { ::memcpy(p, &value, sizeof(T)); } } template< ss_typename_param_k T , ss_typename_param_k A > void do_construct_2(A& /* ator */, T* /* p */, ss_size_t /* n */, T const& value, three_type) {} template< ss_typename_param_k T , ss_typename_param_k A > void do_copy_construct_1(A& ator, T* p, T const* src, ss_size_t n, one_type) { for(T* e = p + n; p != e; ++p, ++src) { ator.construct(p, *src); } } template< ss_typename_param_k T , ss_typename_param_k A > void do_copy_construct_1(A& /* ator */, T* p, T const* src, ss_size_t n, two_type) { for(T* e = p + n; p != e; ++p, ++src) { ::memcpy(p, src, sizeof(T)); } } template< ss_typename_param_k T , ss_typename_param_k A > void do_copy_construct_1(A& /* ator */, T* /* p */, T const* /* src */, ss_size_t /* n */, three_type) {} template< ss_typename_param_k T , ss_typename_param_k A > void do_destroy_1(A& ator, T* p, ss_size_t n, one_type) { for(T* e = p + n; p != e; ++p) { ator.destroy(p); } } template< ss_typename_param_k T , ss_typename_param_k A > void do_destroy_1(A& /* ator */, T* /* p */, ss_size_t /* n */, two_type) {} template< ss_typename_param_k T , ss_typename_param_k A > void do_destroy_1(A& /* ator */, T* /* p */, ss_size_t /* n */, three_type) {} #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */ /* ///////////////////////////////////////////////////////////////////////// * Helper classes */ #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION template< ss_typename_param_k T , ss_typename_param_k A , ss_typename_param_k P > struct array_range_initialiser { public: typedef T value_type; typedef T* pointer; typedef T const* const_pointer; typedef A allocator_type; typedef P initialisation_policy_type; private: # if defined(STLSOFT_COMPILER_IS_MSVC) && \ _MSC_VER < 1310 typedef initialisation_policy_type::type selector_type; # else /* ? compiler */ typedef ss_typename_type_k initialisation_policy_type::type selector_type; # endif /* compiler */ public: /// \brief Performs in-place default construction of n elements, whose first element /// is located at p /// /// \note If the initialisation policy is 'true', then the value_type is assumed to be /// of non-POD type, and therefore constructed. If 'false', then the value_type is /// assumed to be POD and the memory is zero-filled (via memset()) static void construct(allocator_type& ator, pointer p, ss_size_t n) { do_construct_1(ator, p, n, selector_type()); } /// \brief Performs in-place copy construction of n elements, whose first element /// is located at p, where *(p + n) is set to *(src + n) static void copy_construct(allocator_type& ator, pointer p, const_pointer src, ss_size_t n) { do_copy_construct_1(ator, p, src, n, selector_type()); } /// \brief Performs in-place copy construction of n elements, whose first element /// is located at p, where each element == val static void construct(allocator_type& ator, pointer p, ss_size_t n, value_type const& val) { do_construct_2(ator, p, n, val, selector_type()); } static void destroy(allocator_type& ator, pointer p, ss_size_t n) { do_destroy_1(ator, p, n, selector_type()); } }; #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */ /* ////////////////////////////////////////////////////////////////////// */ #ifndef _STLSOFT_NO_NAMESPACE } // namespace stlsoft #endif /* _STLSOFT_NO_NAMESPACE */ /* ////////////////////////////////////////////////////////////////////// */ #endif /* !STLSOFT_INCL_STLSOFT_CONTAINERS_UTIL_HPP_ARRAY_POLICIES */ /* ///////////////////////////// end of file //////////////////////////// */