Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Vc/array is written in an unsupported language. File is not indexed.

0001 /*  This file is part of the Vc library. {{{
0002 Copyright © 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 //===---------------------------- array -----------------------------------===//
0028 //
0029 //                     The LLVM Compiler Infrastructure
0030 //
0031 // This file is dual licensed under the MIT and the University of Illinois Open
0032 // Source Licenses. See LICENSE.TXT for details.
0033 //
0034 //===----------------------------------------------------------------------===//
0035 
0036 #ifndef VC_INCLUDE_VC_ARRAY_
0037 #define VC_INCLUDE_VC_ARRAY_
0038 
0039 #include <type_traits>
0040 #include <utility>
0041 #include <iterator>
0042 #include <algorithm>
0043 #include <stdexcept>
0044 
0045 #include "common/subscript.h"
0046 
0047 namespace Vc_VERSIONED_NAMESPACE
0048 {
0049 /**
0050  * \ingroup Containers
0051  * This is `std::array` with additional subscript operators supporting gather and scatter operations.
0052  *
0053  * The [std::array](https://en.cppreference.com/w/cpp/container/array) documentation applies.
0054  *
0055  * Gathers from structured data (AoS: arrays of struct) are possible via a special
0056  * subscript operator.
0057  * Example:
0058  * \code
0059  * Vc::array<float, 100> data;
0060  * std::iota(data.begin(), data.end(), 0.f);  // fill with values 0, 1, 2, ...
0061  * auto indexes = float_v::IndexType::IndexesFromZero();
0062  * float_v gathered = data[indexes];  // gathered == [0, 1, 2, ...]
0063  * \endcode
0064  *
0065  * This also works for gathers into arrays of structures:
0066  * \code
0067  * struct Point { float x, y, z; };
0068  * Vc::array<Point, 100> points;
0069  * // fill points ...
0070  * auto indexes = float_v::IndexType::IndexesFromZero();
0071  * float_v xs = data[indexes][&Point::x];  // [points[0].x, points[1].x, points[2].x, ...]
0072  * float_v ys = data[indexes][&Point::y];  // [points[0].y, points[1].y, points[2].y, ...]
0073  * float_v zs = data[indexes][&Point::z];  // [points[0].z, points[1].z, points[2].z, ...]
0074  * \endcode
0075  *
0076  * Arrays may also be nested:
0077  * \code:
0078  * Vc::array<Vc::array<float, 3>, 100> points;
0079  * // fill points ...
0080  * auto indexes = float_v::IndexType::IndexesFromZero();
0081  * float_v xs = data[indexes][0];  // [points[0][0], points[1][0], points[2][0], ...]
0082  * float_v ys = data[indexes][1];  // [points[0][1], points[1][1], points[2][1], ...]
0083  * float_v zs = data[indexes][2];  // [points[0][2], points[1][2], points[2][2], ...]
0084  * \endcode
0085  */
0086 template <class T, size_t Size> struct array {
0087     // types:
0088     typedef array self_;
0089     typedef T value_type;
0090     typedef value_type& reference;
0091     typedef const value_type& const_reference;
0092     typedef value_type* iterator;
0093     typedef const value_type* const_iterator;
0094     typedef value_type* pointer;
0095     typedef const value_type* const_pointer;
0096     typedef size_t size_type;
0097     typedef ptrdiff_t difference_type;
0098     typedef std::reverse_iterator<iterator> reverse_iterator;
0099     typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
0100 
0101     value_type elems_[Size > 0 ? Size : 1];
0102 
0103     // No explicit construct/copy/destroy for aggregate type
0104     void fill(const value_type& u_) { std::fill_n(elems_, Size, u_); }
0105     void swap(array& a_) noexcept(std::swap(std::declval<T &>(), std::declval<T &>()))
0106     {
0107         std::swap_ranges(elems_, elems_ + Size, a_.elems_);
0108     }
0109 
0110     // iterators:
0111     iterator begin() noexcept { return iterator(elems_); }
0112     const_iterator begin() const noexcept { return const_iterator(elems_); }
0113     iterator end() noexcept { return iterator(elems_ + Size); }
0114     const_iterator end() const noexcept { return const_iterator(elems_ + Size); }
0115     reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
0116     const_reverse_iterator rbegin() const noexcept
0117     {
0118         return const_reverse_iterator(end());
0119     }
0120     reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
0121     const_reverse_iterator rend() const noexcept
0122     {
0123         return const_reverse_iterator(begin());
0124     }
0125 
0126     const_iterator cbegin() const noexcept { return begin(); }
0127     const_iterator cend() const noexcept { return end(); }
0128     const_reverse_iterator crbegin() const noexcept { return rbegin(); }
0129     const_reverse_iterator crend() const noexcept { return rend(); }
0130     // capacity:
0131     constexpr size_type size() const noexcept { return Size; }
0132     constexpr size_type max_size() const noexcept { return Size; }
0133     constexpr bool empty() const noexcept { return Size == 0; }
0134     // element access:
0135     reference operator[](size_type n_) { return elems_[n_]; }
0136     constexpr const_reference operator[](size_type n_) const { return elems_[n_]; }
0137 
0138     /**
0139      * \name Data-Parallel Subscripting for Gather & Scatter
0140      */
0141     ///@{
0142     template <typename I>
0143     Vc_ALWAYS_INLINE auto operator[](I&& arg_)
0144         -> decltype(subscript_operator(*this, std::forward<I>(arg_)))
0145     {
0146         return subscript_operator(*this, std::forward<I>(arg_));
0147     }
0148 
0149     template <typename I>
0150     Vc_ALWAYS_INLINE auto operator[](I&& arg_) const
0151         -> decltype(subscript_operator(*this, std::forward<I>(arg_)))
0152     {
0153         return subscript_operator(*this, std::forward<I>(arg_));
0154     }
0155     ///@}
0156 
0157     reference at(size_type n_);
0158     constexpr const_reference at(size_type n_) const;
0159 
0160     reference front() { return elems_[0]; }
0161     constexpr const_reference front() const { return elems_[0]; }
0162     reference back() { return elems_[Size > 0 ? Size - 1 : 0]; }
0163     constexpr const_reference back() const { return elems_[Size > 0 ? Size - 1 : 0]; }
0164     value_type* data() noexcept { return elems_; }
0165     const value_type* data() const noexcept { return elems_; }
0166 };
0167 
0168 template <class T, size_t Size>
0169 typename array<T, Size>::reference array<T, Size>::at(size_type n_)
0170 {
0171     if (n_ >= Size) {
0172         throw std::out_of_range("array::at");
0173     }
0174     return elems_[n_];
0175 }
0176 
0177 template <class T, size_t Size>
0178 constexpr typename array<T, Size>::const_reference array<T, Size>::at(size_type n_) const
0179 {
0180     return n_ >= Size ? (throw std::out_of_range("array::at"), elems_[0]) : elems_[n_];
0181 }
0182 
0183 template <class T, size_t Size>
0184 inline bool operator==(const array<T, Size>& x_, const array<T, Size>& y_)
0185 {
0186     return std::equal(x_.elems_, x_.elems_ + Size, y_.elems_);
0187 }
0188 
0189 template <class T, size_t Size>
0190 inline bool operator!=(const array<T, Size>& x_, const array<T, Size>& y_)
0191 {
0192     return !(x_ == y_);
0193 }
0194 
0195 template <class T, size_t Size>
0196 inline bool operator<(const array<T, Size>& x_, const array<T, Size>& y_)
0197 {
0198     return std::lexicographical_compare(x_.elems_, x_.elems_ + Size, y_.elems_,
0199                                         y_.elems_ + Size);
0200 }
0201 
0202 template <class T, size_t Size>
0203 inline bool operator>(const array<T, Size>& x_, const array<T, Size>& y_)
0204 {
0205     return y_ < x_;
0206 }
0207 
0208 template <class T, size_t Size>
0209 inline bool operator<=(const array<T, Size>& x_, const array<T, Size>& y_)
0210 {
0211     return !(y_ < x_);
0212 }
0213 
0214 template <class T, size_t Size>
0215 inline bool operator>=(const array<T, Size>& x_, const array<T, Size>& y_)
0216 {
0217     return !(x_ < y_);
0218 }
0219 
0220 /**\name non-member begin & end
0221  * Implement the non-member begin & end functions in the %Vc namespace so that ADL works
0222  * and `begin(some_vc_array)` always works.
0223  */
0224 ///@{
0225 template <typename T, std::size_t N>
0226 inline auto begin(array<T, N>& arr) -> decltype(arr.begin())
0227 {
0228     return arr.begin();
0229 }
0230 template <typename T, std::size_t N>
0231 inline auto begin(const array<T, N>& arr) -> decltype(arr.begin())
0232 {
0233     return arr.begin();
0234 }
0235 template <typename T, std::size_t N>
0236 inline auto end(array<T, N>& arr) -> decltype(arr.end())
0237 {
0238     return arr.end();
0239 }
0240 template <typename T, std::size_t N>
0241 inline auto end(const array<T, N>& arr) -> decltype(arr.end())
0242 {
0243     return arr.end();
0244 }
0245 ///@}
0246 
0247 namespace Traits
0248 {
0249 template <typename T, std::size_t N>
0250 struct has_no_allocated_data_impl<Vc::array<T, N>> : public std::true_type
0251 {
0252 };
0253 template <typename T, std::size_t N>
0254 struct has_contiguous_storage_impl<Vc::array<T, N>> : public std::true_type
0255 {
0256 };
0257 }  // namespace Traits
0258 }  // namespace Vc
0259 
0260 namespace std
0261 {
0262 template <class T, size_t Size>
0263 inline
0264 #ifdef Vc_MSVC
0265     // MSVC fails to do SFINAE correctly and gets totally confused:
0266     // error C2433: 'type': 'inline' not permitted on data declarations
0267     // error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
0268     // error C2061: syntax error: identifier 'swap'
0269     void
0270 #else
0271     typename enable_if<is_same<void, decltype(swap(declval<T&>(), declval<T&>()))>::value,
0272                        void>::type
0273 #endif
0274     swap(const Vc::array<T, Size>& x_,
0275          const Vc::array<T, Size>& y_) noexcept(swap(declval<T&>(), declval<T&>()))
0276 {
0277     x_.swap(y_);
0278 }
0279 
0280 template <class T, size_t Size>
0281 class tuple_size<Vc::array<T, Size>> : public integral_constant<size_t, Size>
0282 {
0283 };
0284 
0285 template <size_t I, class T, size_t Size> class tuple_element<I, Vc::array<T, Size>>
0286 {
0287 public:
0288     typedef T type;
0289 };
0290 
0291 template <size_t I, class T, size_t Size>
0292 inline constexpr typename std::enable_if<(I < Size), T&>::type get(
0293     Vc::array<T, Size>& a_) noexcept
0294 {
0295     return a_.elems_[I];
0296 }
0297 
0298 template <size_t I, class T, size_t Size>
0299 inline constexpr typename std::enable_if<(I < Size), const T&>::type get(
0300     const Vc::array<T, Size>& a_) noexcept
0301 {
0302     return a_.elems_[I];
0303 }
0304 
0305 template <size_t I, class T, size_t Size>
0306 inline constexpr typename std::enable_if<(I < Size), T&&>::type get(
0307     Vc::array<T, Size>&& a_) noexcept
0308 {
0309     return std::move(a_.elems_[I]);
0310 }
0311 }  // namespace std
0312 
0313 #endif  // VC_INCLUDE_VC_ARRAY_
0314 
0315 // vim: ft=cpp foldmethod=marker