|
||||
File indexing completed on 2025-01-30 10:25:47
0001 /* This file is part of the Vc library. {{{ 0002 Copyright © 2013-2015 Matthias Kretz <kretz@kde.org> 0003 0004 Redistribution and use in source and binary forms, with or without 0005 modification, are permitted provided that the following conditions are met: 0006 * Redistributions of source code must retain the above copyright 0007 notice, this list of conditions and the following disclaimer. 0008 * Redistributions in binary form must reproduce the above copyright 0009 notice, this list of conditions and the following disclaimer in the 0010 documentation and/or other materials provided with the distribution. 0011 * Neither the names of contributing organizations nor the 0012 names of its contributors may be used to endorse or promote products 0013 derived from this software without specific prior written permission. 0014 0015 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 0016 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 0017 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 0018 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY 0019 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 0020 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 0021 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 0022 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0023 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 0024 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0025 0026 }}}*/ 0027 0028 #ifndef VC_COMMON_MAKECONTAINER_H_ 0029 #define VC_COMMON_MAKECONTAINER_H_ 0030 0031 #include "../vector.h" 0032 #include <initializer_list> 0033 0034 namespace Vc_VERSIONED_NAMESPACE 0035 { 0036 0037 namespace 0038 { 0039 template<typename Container, typename T> struct make_container_helper 0040 { 0041 static constexpr Container help(std::initializer_list<T> list) { return { list }; } 0042 }; 0043 0044 template <typename T_, typename Abi, typename Alloc, 0045 template <class, class> class Container> 0046 struct make_container_helper<Container<Vector<T_, Abi>, Alloc>, 0047 typename Vector<T_, Abi>::EntryType> { 0048 typedef Vector<T_, Abi> V; 0049 typedef typename V::EntryType T; 0050 typedef Container<V, Alloc> C; 0051 static inline C help(std::initializer_list<T> list) { 0052 const std::size_t size = (list.size() + (V::Size - 1)) / V::Size; 0053 C v(size); 0054 auto containerIt = v.begin(); 0055 auto init = std::begin(list); 0056 const auto initEnd = std::end(list); 0057 for (std::size_t i = 0; i < size - 1; ++i) { 0058 *containerIt++ = V(init, Vc::Unaligned); 0059 init += V::Size; 0060 } 0061 Vc_ASSERT(all_of(*containerIt == V::Zero())); 0062 int j = 0; 0063 while (init != initEnd) { 0064 (*containerIt)[j++] = *init++; 0065 } 0066 return v; 0067 } 0068 }; 0069 0070 template <typename T_, typename Abi, std::size_t N, 0071 template <class, std::size_t> class Container> 0072 struct make_container_helper<Container<Vector<T_, Abi>, N>, 0073 typename Vector<T_, Abi>::EntryType> { 0074 typedef Vector<T_, Abi> V; 0075 typedef typename V::EntryType T; 0076 static constexpr std::size_t size = (N + (V::Size - 1)) / V::Size; 0077 typedef Container< 0078 V, 0079 #if defined Vc_CLANG && Vc_CLANG < 0x30700 // TODO: when did Vc_APPLECLANG fix it? 0080 // clang before 3.7.0 has a bug when returning std::array<__m256x, 1>. So 0081 // increase it to std::array<__m256x, 2> and fill it with zeros. Better 0082 // than returning garbage. 0083 (size == 1 && std::is_same<Abi, VectorAbi::Avx>::value) ? 2 : 0084 #endif 0085 size> C; 0086 static inline C help(std::initializer_list<T> list) { 0087 Vc_ASSERT(N == list.size()) 0088 Vc_ASSERT(size == (list.size() + (V::Size - 1)) / V::Size) 0089 C v; 0090 auto containerIt = v.begin(); 0091 auto init = std::begin(list); 0092 const auto initEnd = std::end(list); 0093 for (std::size_t i = 0; i < size - 1; ++i) { 0094 *containerIt++ = V(init, Vc::Unaligned); 0095 init += V::Size; 0096 } 0097 Vc_ASSERT(all_of(*containerIt == V::Zero())); 0098 int j = 0; 0099 while (init != initEnd) { 0100 (*containerIt)[j++] = *init++; 0101 } 0102 return v; 0103 } 0104 }; 0105 } // anonymous namespace 0106 0107 /** 0108 * \ingroup Containers 0109 * \headerfile makeContainer.h <Vc/Utils> 0110 * 0111 * Construct a container of Vc vectors from a std::initializer_list of scalar entries. 0112 * 0113 * \tparam Container The container type to construct. 0114 * \tparam T The scalar type to use for the initializer_list. 0115 * 0116 * \param list An initializer list of arbitrary size. The type of the entries is important! 0117 * If you pass a list of integers you will get a container filled with Vc::int_v objects. 0118 * If, instead, you want to have a container of Vc::float_v objects, be sure the include a 0119 * period (.) and the 'f' postfix in the literals. Alternatively, you can pass the 0120 * type as second template argument to makeContainer. 0121 * 0122 * \return Returns a container of the requested class filled with the minimum number of SIMD 0123 * vectors to hold the values in the initializer list. 0124 * If the number of values in \p list does not match the number of values in the 0125 * returned container object, the remaining values in the returned object will be 0126 * zero-initialized. 0127 * 0128 * Example: 0129 * \code 0130 * auto data = Vc::makeContainer<std::vector<float_v>>({ 1.f, 2.f, 3.f, 4.f, 5.f }); 0131 * // data.size() == 5 if float_v::Size == 1 (i.e. Vc_IMPL=Scalar) 0132 * // data.size() == 2 if float_v::Size == 4 (i.e. Vc_IMPL=SSE) 0133 * // data.size() == 1 if float_v::Size == 8 (i.e. Vc_IMPL=AVX) 0134 * \endcode 0135 */ 0136 template<typename Container, typename T> 0137 constexpr auto makeContainer(std::initializer_list<T> list) -> decltype(make_container_helper<Container, T>::help(list)) 0138 { 0139 return make_container_helper<Container, T>::help(list); 0140 } 0141 0142 template<typename Container, typename T> 0143 constexpr auto make_container(std::initializer_list<T> list) -> decltype(makeContainer<Container, T>(list)) 0144 { 0145 return makeContainer<Container, T>(list); 0146 } 0147 0148 } // namespace Vc 0149 0150 #endif // VC_COMMON_MAKECONTAINER_H_
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |