Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:54:46

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2020-2024 UT-Battelle, LLC, and other Celeritas developers.
0003 // See the top-level COPYRIGHT file for details.
0004 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0005 //---------------------------------------------------------------------------//
0006 //! \file corecel/cont/Array.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include <cstddef>
0011 #include <utility>
0012 
0013 #include "corecel/Macros.hh"
0014 #include "corecel/Types.hh"
0015 
0016 namespace celeritas
0017 {
0018 //---------------------------------------------------------------------------//
0019 /*!
0020  * Fixed-size simple array for storage.
0021  *
0022  * The Array class is primarily used for point coordinates (e.g., \c Real3) but
0023  * is also used for other fixed-size data structures.
0024  *
0025  * This isn't fully standards-compliant with std::array: there's no support for
0026  * N=0 for example. Additionally it uses the native celeritas \c size_type,
0027  * even though this has *no* effect on generated code for values of N inside
0028  * the range of \c size_type.
0029  *
0030  * \note For supplementary functionality, include:
0031  * - \c corecel/math/ArrayUtils.hh for real-number vector/matrix applications
0032  * - \c corecel/math/ArrayOperators.hh for mathematical operators
0033  * - \c ArrayIO.hh for streaming and string conversion
0034  * - \c ArrayIO.json.hh for JSON input and output
0035  */
0036 template<class T, ::celeritas::size_type N>
0037 struct Array
0038 {
0039     //!@{
0040     //! \name Type aliases
0041     using value_type = T;
0042     using size_type = ::celeritas::size_type;
0043     using pointer = value_type*;
0044     using const_pointer = value_type const*;
0045     using reference = value_type&;
0046     using const_reference = value_type const&;
0047     using iterator = pointer;
0048     using const_iterator = const_pointer;
0049     //!@}
0050 
0051     //// DATA ////
0052 
0053     T data_[N];  //!< Storage
0054 
0055     //// ACCESSORS ////
0056 
0057     //!@{
0058     //! \name Element access
0059     CELER_CONSTEXPR_FUNCTION const_reference operator[](size_type i) const
0060     {
0061         return data_[i];
0062     }
0063     CELER_CONSTEXPR_FUNCTION reference operator[](size_type i)
0064     {
0065         return data_[i];
0066     }
0067     CELER_CONSTEXPR_FUNCTION const_reference front() const { return data_[0]; }
0068     CELER_CONSTEXPR_FUNCTION reference front() { return data_[0]; }
0069     CELER_CONSTEXPR_FUNCTION const_reference back() const
0070     {
0071         return data_[N - 1];
0072     }
0073     CELER_CONSTEXPR_FUNCTION reference back() { return data_[N - 1]; }
0074     CELER_CONSTEXPR_FUNCTION const_pointer data() const { return data_; }
0075     CELER_CONSTEXPR_FUNCTION pointer data() { return data_; }
0076 
0077     //! Access for structured unpacking
0078     template<std::size_t I>
0079     CELER_CONSTEXPR_FUNCTION T& get()
0080     {
0081         static_assert(I < static_cast<std::size_t>(N));
0082         return data_[I];
0083     }
0084 
0085     //! Access for structured unpacking
0086     template<std::size_t I>
0087     CELER_CONSTEXPR_FUNCTION T const& get() const
0088     {
0089         static_assert(I < static_cast<std::size_t>(N));
0090         return data_[I];
0091     }
0092     //!@}
0093 
0094     //!@{
0095     //! \name Iterators
0096     CELER_CONSTEXPR_FUNCTION iterator begin() { return data_; }
0097     CELER_CONSTEXPR_FUNCTION iterator end() { return data_ + N; }
0098     CELER_CONSTEXPR_FUNCTION const_iterator begin() const { return data_; }
0099     CELER_CONSTEXPR_FUNCTION const_iterator end() const { return data_ + N; }
0100     CELER_CONSTEXPR_FUNCTION const_iterator cbegin() const { return data_; }
0101     CELER_CONSTEXPR_FUNCTION const_iterator cend() const { return data_ + N; }
0102     //!@}
0103 
0104     //!@{
0105     //! \name Capacity
0106     CELER_CONSTEXPR_FUNCTION bool empty() const { return N == 0; }
0107     static CELER_CONSTEXPR_FUNCTION size_type size() { return N; }
0108     //!@}
0109 
0110     //!@{
0111     //! \name  Operations
0112     //! Fill the array with a constant value
0113     CELER_CONSTEXPR_FUNCTION void fill(const_reference value)
0114     {
0115         for (size_type i = 0; i != N; ++i)
0116             data_[i] = value;
0117     }
0118     //!@}
0119 };
0120 
0121 //---------------------------------------------------------------------------//
0122 // INLINE DEFINITIONS
0123 //---------------------------------------------------------------------------//
0124 /*!
0125  * Test equality of two arrays.
0126  */
0127 template<class T, size_type N>
0128 CELER_CONSTEXPR_FUNCTION bool
0129 operator==(Array<T, N> const& lhs, Array<T, N> const& rhs)
0130 {
0131     for (size_type i = 0; i != N; ++i)
0132     {
0133         if (lhs[i] != rhs[i])
0134             return false;
0135     }
0136     return true;
0137 }
0138 
0139 //---------------------------------------------------------------------------//
0140 /*!
0141  * Test inequality of two arrays.
0142  */
0143 template<class T, size_type N>
0144 CELER_CONSTEXPR_FUNCTION bool
0145 operator!=(Array<T, N> const& lhs, Array<T, N> const& rhs)
0146 {
0147     return !(lhs == rhs);
0148 }
0149 
0150 //---------------------------------------------------------------------------//
0151 }  // namespace celeritas
0152 
0153 //---------------------------------------------------------------------------//
0154 //! \cond
0155 namespace std
0156 {
0157 //---------------------------------------------------------------------------//
0158 //! Support structured binding: array size
0159 template<class T, celeritas::size_type N>
0160 struct tuple_size<celeritas::Array<T, N>>
0161 {
0162     static constexpr std::size_t value = N;
0163 };
0164 
0165 //! Support structured binding: array element type
0166 template<std::size_t I, class T, celeritas::size_type N>
0167 struct tuple_element<I, celeritas::Array<T, N>>
0168 {
0169     static_assert(I < std::tuple_size<celeritas::Array<T, N>>::value);
0170     using type = T;
0171 };
0172 
0173 //---------------------------------------------------------------------------//
0174 }  // namespace std
0175 //! \endcond