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/Range.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include "detail/RangeImpl.hh"
0011 
0012 namespace celeritas
0013 {
0014 //---------------------------------------------------------------------------//
0015 /*!
0016  * \fn range
0017  * \tparam T Value type to iterate over
0018  * Get iterators over a range of values, or a semi-infinite range.
0019  *
0020  * \par Code Sample:
0021  * \code
0022 
0023     for (auto i : Range(1, 5))
0024         cout << i << "\n";
0025 
0026     // Range of [0, 10)
0027     for (auto u : Range(10u))
0028         cout << u << "\n";
0029 
0030     for (auto c : Range('a', 'd'))
0031         cout << c << "\n";
0032 
0033     for (auto i : Count(100).step(-3))
0034         if (i < 90) break;
0035         else        cout << i << "\n";
0036 
0037  * \endcode
0038  */
0039 
0040 //! Publicly expose traits for countable (OpaqueId, enum, init) type T
0041 template<class T>
0042 using RangeIter = detail::range_iter<T>;
0043 
0044 //---------------------------------------------------------------------------//
0045 /*!
0046  * Proxy container for iterating over a range of integral values.
0047  *
0048  * Here, T can be any of:
0049  * - an integer,
0050  * - an enum that has contiguous zero-indexed values and a "size_" enumeration
0051  *   value indicating how many, or
0052  * - an OpaqueId.
0053  *
0054  * It is OK to dereference the end iterator! The result should just be the
0055  * off-the-end value for the range, e.g. `FooEnum::size_` or `bar.size()`.
0056  */
0057 template<class T>
0058 class Range
0059 {
0060     using TraitsT = detail::RangeTypeTraits<T>;
0061 
0062   public:
0063     //!@{
0064     //! \name Type aliases
0065     using const_iterator = detail::range_iter<T>;
0066     using size_type = typename TraitsT::counter_type;
0067     using value_type = T;
0068     //@}
0069 
0070     template<class U>
0071     using step_type = typename TraitsT::template common_type<U>;
0072 
0073   public:
0074     //// CONSTRUCTORS ////
0075 
0076     //! Empty constructor for empty range
0077     CELER_CONSTEXPR_FUNCTION Range() : begin_{}, end_{} {}
0078 
0079     //! Construct from stop
0080     CELER_CONSTEXPR_FUNCTION Range(T end) : begin_{}, end_(end) {}
0081 
0082     //! Construct from start/stop
0083     CELER_CONSTEXPR_FUNCTION Range(T begin, T end) : begin_(begin), end_(end)
0084     {
0085     }
0086 
0087     //// CONTAINER-LIKE ACCESS ////
0088 
0089     //!@{
0090     //! Iterators
0091     CELER_CONSTEXPR_FUNCTION const_iterator begin() const { return begin_; }
0092     CELER_CONSTEXPR_FUNCTION const_iterator cbegin() const { return begin_; }
0093     CELER_CONSTEXPR_FUNCTION const_iterator end() const { return end_; }
0094     CELER_CONSTEXPR_FUNCTION const_iterator cend() const { return end_; }
0095     //!@}
0096 
0097     //! Array-like access
0098     CELER_CONSTEXPR_FUNCTION value_type operator[](size_type i) const
0099     {
0100         return *(begin_ + i);
0101     }
0102 
0103     //! Number of elements
0104     CELER_CONSTEXPR_FUNCTION size_type size() const
0105     {
0106         return TraitsT::to_counter(*end_) - TraitsT::to_counter(*begin_);
0107     }
0108 
0109     //! Whether the range has no elements
0110     CELER_CONSTEXPR_FUNCTION bool empty() const { return begin_ == end_; }
0111 
0112     //! First item in the range
0113     CELER_CONSTEXPR_FUNCTION value_type front() const { return *begin_; }
0114 
0115     //! Last item in the range
0116     CELER_CONSTEXPR_FUNCTION value_type back() const
0117     {
0118         return (*this)[this->size() - 1];
0119     }
0120 
0121     //// STRIDED ACCESS ////
0122 
0123     //! Return a stepped range using a *signed* integer type
0124     template<class U, std::enable_if_t<std::is_signed<U>::value, bool> = true>
0125     CELER_CONSTEXPR_FUNCTION detail::StepRange<step_type<U>> step(U step)
0126     {
0127         if (step < 0)
0128         {
0129             return {TraitsT::increment(*end_, step), *begin_, step};
0130         }
0131 
0132         return {*begin_, *end_, step};
0133     }
0134 
0135     //! \cond
0136     //! Return a stepped range using an *unsigned* integer type
0137     template<class U, std::enable_if_t<std::is_unsigned<U>::value, bool> = true>
0138     CELER_CONSTEXPR_FUNCTION detail::StepRange<step_type<U>> step(U step)
0139     {
0140         return {*begin_, *end_, static_cast<size_type>(step)};
0141     }
0142     //! \endcond
0143 
0144   private:
0145     const_iterator begin_;
0146     const_iterator end_;
0147 };
0148 
0149 //---------------------------------------------------------------------------//
0150 /*!
0151  * Proxy container for an unbounded range with a given start value.
0152  */
0153 template<class T>
0154 class Count
0155 {
0156     using TraitsT = detail::RangeTypeTraits<T>;
0157 
0158   public:
0159     //!@{
0160     //! \name Type aliases
0161     using const_iterator = detail::inf_range_iter<T>;
0162     using size_type = typename TraitsT::counter_type;
0163     using value_type = T;
0164     //@}
0165 
0166     CELER_CONSTEXPR_FUNCTION Count() : begin_{} {}
0167     CELER_CONSTEXPR_FUNCTION Count(T begin) : begin_(begin) {}
0168 
0169     CELER_CONSTEXPR_FUNCTION detail::InfStepRange<T> step(T step)
0170     {
0171         return {*begin_, step};
0172     }
0173 
0174     CELER_CONSTEXPR_FUNCTION const_iterator begin() const { return begin_; }
0175     CELER_CONSTEXPR_FUNCTION const_iterator end() const
0176     {
0177         return const_iterator();
0178     }
0179     CELER_CONSTEXPR_FUNCTION bool empty() const { return false; }
0180 
0181   private:
0182     const_iterator begin_;
0183 };
0184 
0185 //---------------------------------------------------------------------------//
0186 /*!
0187  * Return a range over fixed beginning and end values.
0188  */
0189 template<class T>
0190 CELER_CONSTEXPR_FUNCTION Range<T> range(T begin, T end)
0191 {
0192     return {begin, end};
0193 }
0194 
0195 //---------------------------------------------------------------------------//
0196 /*!
0197  * Return a range with the default start value (0 for numeric types)
0198  */
0199 template<class T>
0200 CELER_CONSTEXPR_FUNCTION Range<T> range(T end)
0201 {
0202     return {end};
0203 }
0204 
0205 //---------------------------------------------------------------------------//
0206 /*!
0207  * Count upward from zero.
0208  */
0209 template<class T>
0210 CELER_CONSTEXPR_FUNCTION Count<T> count()
0211 {
0212     return {};
0213 }
0214 
0215 //---------------------------------------------------------------------------//
0216 /*!
0217  * Count upward from a value.
0218  */
0219 template<class T>
0220 CELER_CONSTEXPR_FUNCTION Count<T> count(T begin)
0221 {
0222     return {begin};
0223 }
0224 
0225 //---------------------------------------------------------------------------//
0226 }  // namespace celeritas