@@ -102,6 +102,21 @@ namespace xf
102102 using const_pointer = typename value_traits::const_pointer;
103103 using size_type = typename size_traits::size_type;
104104 using difference_type = typename size_traits::difference_type;
105+
106+ using const_iterator = xtl::variant<typename V::const_iterator...>;
107+ using iterator = std::conditional_t <is_const,
108+ const_iterator,
109+ xtl::variant<typename V::iterator...>>;
110+ };
111+
112+ template <bool is_const, class traits >
113+ struct xvlv_iterator_traits
114+ {
115+ using value_type = typename traits::value_type;
116+ using reference = std::conditional_t <is_const, typename traits::const_reference, typename traits::reference>;
117+ using pointer = std::conditional_t <is_const, typename traits::const_pointer, typename traits::pointer>;
118+ using difference_type = typename traits::difference_type;
119+ using iterator = std::conditional_t <is_const, typename traits::const_iterator, typename traits::iterator>;
105120 };
106121
107122 template <class T1 , class T2 >
@@ -112,6 +127,9 @@ namespace xf
112127 * xvector_like_variant_base *
113128 *****************************/
114129
130+ template <class traits >
131+ class xvector_like_variant_iterator ;
132+
115133 template <class traits >
116134 class xvector_like_variant_base
117135 {
@@ -127,6 +145,11 @@ namespace xf
127145 using difference_type = typename traits::difference_type;
128146 using storage_type = typename traits::storage_type;
129147
148+ using iterator_traits = detail::xvlv_iterator_traits<false , traits>;
149+ using const_iterator_traits = detail::xvlv_iterator_traits<true , traits>;
150+
151+ using iterator = xvector_like_variant_iterator<iterator_traits>;
152+ using const_iterator = xvector_like_variant_iterator<const_iterator_traits>;
130153 // Size and capacity
131154
132155 bool empty () const ;
@@ -160,6 +183,16 @@ namespace xf
160183 storage_type& storage ();
161184 const storage_type& storage () const ;
162185
186+ // Iterators
187+
188+ iterator begin ();
189+ iterator end ();
190+
191+ const_iterator begin () const ;
192+ const_iterator end () const ;
193+
194+ const_iterator cbegin () const ;
195+ const_iterator cend () const ;
163196 // Comparison
164197
165198 bool equal (const self_type& rhs) const ;
@@ -206,6 +239,55 @@ namespace xf
206239 template <class T >
207240 bool operator >=(const xvector_like_variant_base<T>& lhs, const xvector_like_variant_base<T>& rhs);
208241
242+ /* ********************************
243+ * xvector_like_variant_iterator *
244+ *********************************/
245+
246+ template <class traits >
247+ class xvector_like_variant_iterator : public xtl ::xrandom_access_iterator_base<xvector_like_variant_iterator<traits>,
248+ typename traits::value_type,
249+ typename traits::difference_type,
250+ typename traits::pointer,
251+ typename traits::reference>
252+ {
253+ public:
254+
255+ using self_type = xvector_like_variant_iterator<traits>;
256+ using value_type = typename traits::value_type;
257+ using reference = typename traits::reference;
258+ using pointer = typename traits::pointer;
259+ using difference_type = typename traits::difference_type;
260+ using iterator_category = std::random_access_iterator_tag;
261+ using subiterator = typename traits::iterator;
262+
263+ xvector_like_variant_iterator () = default ;
264+ xvector_like_variant_iterator (subiterator it);
265+
266+ self_type& operator ++();
267+ self_type& operator --();
268+
269+ self_type& operator +=(difference_type n);
270+ self_type& operator -=(difference_type n);
271+
272+ difference_type operator -(const self_type& rhs) const ;
273+
274+ reference operator *() const ;
275+ // pointer operator->() const;
276+
277+ bool equal (const self_type& rhs) const ;
278+ bool less_than (const self_type& rhs) const ;
279+
280+ private:
281+
282+ subiterator m_it;
283+ };
284+
285+ template <class T >
286+ bool operator ==(const xvector_like_variant_iterator<T>& lhs, const xvector_like_variant_iterator<T>& rhs);
287+
288+ template <class T >
289+ bool operator <(const xvector_like_variant_iterator<T>& lhs, const xvector_like_variant_iterator<T>& rhs);
290+
209291 /* ***********************
210292 * xvector_like_variant *
211293 ************************/
@@ -477,6 +559,42 @@ namespace xf
477559 return m_storage;
478560 }
479561
562+ template <class T >
563+ inline auto xvector_like_variant_base<T>::begin() -> iterator
564+ {
565+ return xtl::visit ([](auto & arg) { return iterator (detail::unwrap (arg).begin ()); }, m_storage);
566+ }
567+
568+ template <class T >
569+ inline auto xvector_like_variant_base<T>::end() -> iterator
570+ {
571+ return xtl::visit ([](auto & arg) { return iterator (detail::unwrap (arg).end ()); }, m_storage);
572+ }
573+
574+ template <class T >
575+ inline auto xvector_like_variant_base<T>::begin() const -> const_iterator
576+ {
577+ return cbegin ();
578+ }
579+
580+ template <class T >
581+ inline auto xvector_like_variant_base<T>::end() const -> const_iterator
582+ {
583+ return cend ();
584+ }
585+
586+ template <class T >
587+ inline auto xvector_like_variant_base<T>::cbegin() const -> const_iterator
588+ {
589+ return xtl::visit ([](const auto & arg) { return const_iterator (detail::unwrap (arg).cbegin ()); }, m_storage);
590+ }
591+
592+ template <class T >
593+ inline auto xvector_like_variant_base<T>::cend() const -> const_iterator
594+ {
595+ return xtl::visit ([](const auto & arg) { return const_iterator (detail::unwrap (arg).cend ()); }, m_storage);
596+ }
597+
480598 template <class T >
481599 inline bool xvector_like_variant_base<T>::equal(const self_type& rhs) const
482600 {
@@ -525,6 +643,80 @@ namespace xf
525643 return !(lhs < rhs);
526644 }
527645
646+ /* ********************************
647+ * xvector_like_variant_iterator *
648+ *********************************/
649+
650+ template <class T >
651+ inline xvector_like_variant_iterator<T>::xvector_like_variant_iterator(subiterator it)
652+ : m_it(it)
653+ {
654+ }
655+
656+ template <class T >
657+ inline auto xvector_like_variant_iterator<T>::operator ++() -> self_type&
658+ {
659+ xtl::visit ([](auto & arg) { ++arg; }, m_it);
660+ return *this ;
661+ }
662+
663+ template <class T >
664+ inline auto xvector_like_variant_iterator<T>::operator --() -> self_type&
665+ {
666+ xtl::visit ([](auto & arg) { --arg; }, m_it);
667+ return *this ;
668+ }
669+
670+ template <class T >
671+ inline auto xvector_like_variant_iterator<T>::operator +=(difference_type n) -> self_type&
672+ {
673+ xtl::visit ([n](auto & arg) { arg += n; }, m_it);
674+ return *this ;
675+ }
676+
677+ template <class T >
678+ inline auto xvector_like_variant_iterator<T>::operator -=(difference_type n) -> self_type&
679+ {
680+ xtl::visit ([n](auto & arg) { arg -= n; }, m_it);
681+ return *this ;
682+ }
683+
684+ template <class T >
685+ inline auto xvector_like_variant_iterator<T>::operator -(const self_type& rhs) const -> difference_type
686+ {
687+ return xtl::visit ([&rhs](auto & arg) { return arg - xtl::xget<std::decay_t <decltype (arg)>>(rhs.m_it ); }, m_it);
688+ }
689+
690+ template <class T >
691+ inline auto xvector_like_variant_iterator<T>::operator *() const -> reference
692+ {
693+ return xtl::visit ([](auto & arg) { return reference (xtl::closure (*arg)); }, m_it);
694+ }
695+
696+ template <class T >
697+ inline bool xvector_like_variant_iterator<T>::equal(const self_type& rhs) const
698+ {
699+ return m_it == rhs.m_it ;
700+ }
701+
702+ template <class T >
703+ inline bool xvector_like_variant_iterator<T>::less_than(const self_type& rhs) const
704+ {
705+ return m_it < rhs.m_it ;
706+ }
707+
708+ template <class T >
709+ inline bool operator ==(const xvector_like_variant_iterator<T>& lhs, const xvector_like_variant_iterator<T>& rhs)
710+ {
711+ return lhs.equal (rhs);
712+ }
713+
714+ template <class T >
715+ inline bool operator <(const xvector_like_variant_iterator<T>& lhs, const xvector_like_variant_iterator<T>& rhs)
716+ {
717+ return lhs.less_than (rhs);
718+ }
719+
528720 /* **************************************
529721 * xvector_like_variant implementation *
530722 ***************************************/
0 commit comments