Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-01-08 10:09:21

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