Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-14 09:15:19

0001 // Copyright (c) 2026 OPEN CASCADE SAS
0002 //
0003 // This file is part of Open CASCADE Technology software library.
0004 //
0005 // This library is free software; you can redistribute it and/or modify it under
0006 // the terms of the GNU Lesser General Public License version 2.1 as published
0007 // by the Free Software Foundation, with special exception defined in the file
0008 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0009 // distribution for complete text of the license and disclaimer of any warranty.
0010 //
0011 // Alternatively, this file may be used under the terms of Open CASCADE
0012 // commercial license or contractual agreement.
0013 
0014 #ifndef NCollection_ItemsView_HeaderFile
0015 #define NCollection_ItemsView_HeaderFile
0016 
0017 #include <cstddef>
0018 #include <iterator>
0019 #include <tuple>
0020 #include <type_traits>
0021 
0022 //! @file NCollection_ItemsView.hxx
0023 //! @brief Template utilities for key-value pair iteration with structured bindings.
0024 //!
0025 //! This header provides reusable template classes for implementing Items() views
0026 //! across NCollection map classes, enabling C++17 structured binding syntax.
0027 //!
0028 //! All utilities are organized under the NCollection_ItemsView namespace.
0029 
0030 namespace NCollection_ItemsView
0031 {
0032 
0033 //=================================================================================================
0034 
0035 //! Key-value pair reference for structured binding support.
0036 //! Enables: for (auto [key, value] : map.Items())
0037 //! @tparam TheKeyType   the key type
0038 //! @tparam TheValueType the value type
0039 //! @tparam IsConst      if true, value is const reference; if false, mutable reference
0040 template <class TheKeyType, class TheValueType, bool IsConst>
0041 struct KeyValueRef
0042 {
0043   using ValueRef = std::conditional_t<IsConst, const TheValueType&, TheValueType&>;
0044 
0045   const TheKeyType& Key;
0046   ValueRef          Value;
0047 
0048   template <std::size_t I>
0049   decltype(auto) get() const noexcept
0050   {
0051     if constexpr (I == 0)
0052       return Key;
0053     else if constexpr (I == 1)
0054       return Value;
0055   }
0056 };
0057 
0058 //=================================================================================================
0059 
0060 //! Key-value-index tuple reference for structured binding support.
0061 //! Enables: for (auto [key, value, index] : map.IndexedItems())
0062 //! @tparam TheKeyType   the key type
0063 //! @tparam TheValueType the value type
0064 //! @tparam IsConst      if true, value is const reference; if false, mutable reference
0065 template <class TheKeyType, class TheValueType, bool IsConst>
0066 struct KeyValueIndexRef
0067 {
0068   using ValueRef = std::conditional_t<IsConst, const TheValueType&, TheValueType&>;
0069 
0070   const TheKeyType& Key;
0071   ValueRef          Value;
0072   int               Index;
0073 
0074   template <std::size_t I>
0075   decltype(auto) get() const noexcept
0076   {
0077     if constexpr (I == 0)
0078       return Key;
0079     else if constexpr (I == 1)
0080       return Value;
0081     else if constexpr (I == 2)
0082       return Index;
0083   }
0084 };
0085 
0086 //=================================================================================================
0087 
0088 //! Key-index pair reference for structured binding support (key-only indexed maps).
0089 //! Enables: for (auto [key, index] : map.IndexedItems())
0090 //! @tparam TheKeyType the key type
0091 template <class TheKeyType>
0092 struct KeyIndexRef
0093 {
0094   const TheKeyType& Key;
0095   int               Index;
0096 
0097   template <std::size_t I>
0098   decltype(auto) get() const noexcept
0099   {
0100     if constexpr (I == 0)
0101       return Key;
0102     else if constexpr (I == 1)
0103       return Index;
0104   }
0105 };
0106 
0107 //=================================================================================================
0108 
0109 //! Generic forward iterator for View classes.
0110 //! @tparam BaseIterator the map's native Iterator type
0111 //! @tparam RefType      the reference type returned by operator*
0112 //! @tparam Extractor    functor class with static Extract(iter) returning RefType
0113 template <class BaseIterator, class RefType, class Extractor>
0114 class Iterator
0115 {
0116 public:
0117   using iterator_category = std::forward_iterator_tag;
0118   using value_type        = RefType;
0119   using difference_type   = std::ptrdiff_t;
0120   using pointer           = void;
0121   using reference         = RefType;
0122 
0123   //! Default constructor (creates end iterator)
0124   Iterator() = default;
0125 
0126   //! Constructor from map
0127   template <class MapType>
0128   explicit Iterator(const MapType& theMap)
0129       : myInner(theMap)
0130   {
0131   }
0132 
0133   //! Dereference operator
0134   RefType operator*() const { return Extractor::Extract(myInner); }
0135 
0136   //! Prefix increment
0137   Iterator& operator++()
0138   {
0139     myInner.Next();
0140     return *this;
0141   }
0142 
0143   //! Postfix increment
0144   Iterator operator++(int)
0145   {
0146     Iterator aTmp = *this;
0147     ++(*this);
0148     return aTmp;
0149   }
0150 
0151   //! Equality comparison
0152   bool operator==(const Iterator& theOther) const
0153   {
0154     return myInner.More() == theOther.myInner.More()
0155            && (!myInner.More() || myInner.IsEqual(theOther.myInner));
0156   }
0157 
0158   //! Inequality comparison
0159   bool operator!=(const Iterator& theOther) const { return !(*this == theOther); }
0160 
0161 private:
0162   mutable BaseIterator myInner;
0163 };
0164 
0165 //=================================================================================================
0166 
0167 //! Generic view class for Items() iteration.
0168 //! @tparam MapType   the map class type
0169 //! @tparam RefType   the reference type for structured bindings
0170 //! @tparam Extractor functor class for extracting RefType from iterator
0171 //! @tparam IsConst   if true, this is a const view
0172 template <class MapType, class RefType, class Extractor, bool IsConst>
0173 class View
0174 {
0175 public:
0176   using MapRef   = std::conditional_t<IsConst, const MapType&, MapType&>;
0177   using iterator = Iterator<typename MapType::Iterator, RefType, Extractor>;
0178 
0179   //! Constructor
0180   explicit View(MapRef theMap)
0181       : myMap(theMap)
0182   {
0183   }
0184 
0185   //! Returns iterator to first element
0186   iterator begin() const { return iterator(myMap); }
0187 
0188   //! Returns iterator past the end
0189   iterator end() const { return iterator(); }
0190 
0191 private:
0192   MapRef myMap;
0193 };
0194 
0195 } // namespace NCollection_ItemsView
0196 
0197 //=================================================================================================
0198 
0199 // Structured binding support (std::tuple_size and std::tuple_element specializations)
0200 
0201 namespace std
0202 {
0203 
0204 // KeyValueRef tuple interface
0205 template <class TheKeyType, class TheValueType, bool IsConst>
0206 struct tuple_size<NCollection_ItemsView::KeyValueRef<TheKeyType, TheValueType, IsConst>>
0207     : std::integral_constant<std::size_t, 2>
0208 {
0209 };
0210 
0211 template <class TheKeyType, class TheValueType, bool IsConst>
0212 struct tuple_element<0, NCollection_ItemsView::KeyValueRef<TheKeyType, TheValueType, IsConst>>
0213 {
0214   using type = const TheKeyType&;
0215 };
0216 
0217 template <class TheKeyType, class TheValueType, bool IsConst>
0218 struct tuple_element<1, NCollection_ItemsView::KeyValueRef<TheKeyType, TheValueType, IsConst>>
0219 {
0220   using type =
0221     typename NCollection_ItemsView::KeyValueRef<TheKeyType, TheValueType, IsConst>::ValueRef;
0222 };
0223 
0224 // KeyValueIndexRef tuple interface
0225 template <class TheKeyType, class TheValueType, bool IsConst>
0226 struct tuple_size<NCollection_ItemsView::KeyValueIndexRef<TheKeyType, TheValueType, IsConst>>
0227     : std::integral_constant<std::size_t, 3>
0228 {
0229 };
0230 
0231 template <class TheKeyType, class TheValueType, bool IsConst>
0232 struct tuple_element<0, NCollection_ItemsView::KeyValueIndexRef<TheKeyType, TheValueType, IsConst>>
0233 {
0234   using type = const TheKeyType&;
0235 };
0236 
0237 template <class TheKeyType, class TheValueType, bool IsConst>
0238 struct tuple_element<1, NCollection_ItemsView::KeyValueIndexRef<TheKeyType, TheValueType, IsConst>>
0239 {
0240   using type =
0241     typename NCollection_ItemsView::KeyValueIndexRef<TheKeyType, TheValueType, IsConst>::ValueRef;
0242 };
0243 
0244 template <class TheKeyType, class TheValueType, bool IsConst>
0245 struct tuple_element<2, NCollection_ItemsView::KeyValueIndexRef<TheKeyType, TheValueType, IsConst>>
0246 {
0247   using type = int;
0248 };
0249 
0250 // KeyIndexRef tuple interface
0251 template <class TheKeyType>
0252 struct tuple_size<NCollection_ItemsView::KeyIndexRef<TheKeyType>>
0253     : std::integral_constant<std::size_t, 2>
0254 {
0255 };
0256 
0257 template <class TheKeyType>
0258 struct tuple_element<0, NCollection_ItemsView::KeyIndexRef<TheKeyType>>
0259 {
0260   using type = const TheKeyType&;
0261 };
0262 
0263 template <class TheKeyType>
0264 struct tuple_element<1, NCollection_ItemsView::KeyIndexRef<TheKeyType>>
0265 {
0266   using type = int;
0267 };
0268 
0269 } // namespace std
0270 
0271 #endif // NCollection_ItemsView_HeaderFile