1 2 // 3 // This source file is part of appleseed. 4 // Visit https://appleseedhq.net/ for additional information and resources. 5 // 6 // This software is released under the MIT license. 7 // 8 // Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited 9 // Copyright (c) 2014-2018 Francois Beaune, The appleseedhq Organization 10 // 11 // Permission is hereby granted, free of charge, to any person obtaining a copy 12 // of this software and associated documentation files (the "Software"), to deal 13 // in the Software without restriction, including without limitation the rights 14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 // copies of the Software, and to permit persons to whom the Software is 16 // furnished to do so, subject to the following conditions: 17 // 18 // The above copyright notice and this permission notice shall be included in 19 // all copies or substantial portions of the Software. 20 // 21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 // THE SOFTWARE. 28 // 29 30 #pragma once 31 32 // appleseed.foundation headers. 33 #include "foundation/utility/alignedallocator.h" 34 35 // Standard headers. 36 #include <vector> 37 38 namespace foundation 39 { 40 41 // 42 // foundation::AlignedVector is a partial specialization of std::vector for 43 // the foundation::AlignedAllocator memory allocator. 44 // 45 // foundation::AlignedVector also works around a particularity in Visual Studio's 46 // implementation of the STL where std::vector::resize() takes the value of new 47 // elements by value (as it should according to C++03) instead of by constant 48 // reference (as it should according to C++11), preventing using "overly-aligned" 49 // types with std::vector. 50 // 51 // References: 52 // 53 // std::vector of Aligned Elements 54 // http://thetweaker.wordpress.com/2010/05/05/stdvector-of-aligned-elements/ 55 // 56 // std::vector of Aligned Elements Revisited 57 // http://thetweaker.wordpress.com/2010/08/15/stdvector-of-aligned-elements-revisited/ 58 // 59 // StackOverflow: Self-contained, STL-compatible implementation of std::vector 60 // http://stackoverflow.com/questions/9409591/self-contained-stl-compatible-implementation-of-stdvector 61 // 62 // Eigen implementation of this workaround 63 // https://bitbucket.org/eigen/eigen/src/69228ecab94b/Eigen/src/StlSupport/details.h 64 // https://bitbucket.org/eigen/eigen/src/69228ecab94b/Eigen/src/StlSupport/StdVector.h 65 // 66 67 template <typename T> 68 struct VectorElementWrapper 69 : public T 70 { VectorElementWrapperVectorElementWrapper71 VectorElementWrapper() {} VectorElementWrapperVectorElementWrapper72 VectorElementWrapper(const T& rhs) : T(rhs) {} 73 }; 74 75 #ifdef _MSC_VER 76 #define ALIGNED_VECTOR_BASE std::vector<VectorElementWrapper<T>, AlignedAllocator<VectorElementWrapper<T>>> 77 #else 78 #define ALIGNED_VECTOR_BASE std::vector<T, AlignedAllocator<T>> 79 #endif 80 81 template <typename T> 82 class AlignedVector 83 : public ALIGNED_VECTOR_BASE 84 { 85 public: 86 typedef ALIGNED_VECTOR_BASE Base; 87 AlignedVector()88 AlignedVector() 89 { 90 } 91 AlignedVector(const typename Base::allocator_type & allocator)92 explicit AlignedVector(const typename Base::allocator_type& allocator) 93 : Base(allocator) 94 { 95 } 96 AlignedVector(const typename Base::size_type count)97 explicit AlignedVector(const typename Base::size_type count) 98 : Base(count) 99 { 100 } 101 AlignedVector(const typename Base::size_type count,const typename Base::value_type & value)102 AlignedVector( 103 const typename Base::size_type count, 104 const typename Base::value_type& value) 105 : Base(count, value) 106 { 107 } 108 AlignedVector(const typename Base::size_type count,const typename Base::value_type & value,const typename Base::allocator_type & allocator)109 AlignedVector( 110 const typename Base::size_type count, 111 const typename Base::value_type& value, 112 const typename Base::allocator_type& allocator) 113 : Base(count, value, allocator) 114 { 115 } 116 AlignedVector(const Base & rhs)117 AlignedVector(const Base& rhs) 118 : Base(rhs) 119 { 120 } 121 122 template <typename Iterator> AlignedVector(Iterator first,Iterator last)123 AlignedVector(Iterator first, Iterator last) 124 : Base(first, last) 125 { 126 } 127 128 template <typename Iterator> AlignedVector(Iterator first,Iterator last,const typename Base::allocator_type & allocator)129 AlignedVector( 130 Iterator first, 131 Iterator last, 132 const typename Base::allocator_type& allocator) 133 : Base(first, last, allocator) 134 { 135 } 136 AlignedVector(Base && rhs)137 AlignedVector(Base&& rhs) 138 : Base(rhs) 139 { 140 } 141 }; 142 143 #undef ALIGNED_VECTOR_BASE 144 145 } // namespace foundation 146