@@ -687,35 +687,27 @@ class array_hash : private value_container<T>, private Hash, private GrowthPolic
687687
688688public:
689689 template <bool is_const>
690- class array_hash_iterator_with_value ;
691-
692- template <bool is_const>
693- class array_hash_iterator_without_value ;
690+ class array_hash_iterator ;
694691
695692 using traits_type = Traits;
696693 using char_type = CharT;
697694 using key_size_type = KeySizeT;
698695 using index_size_type = IndexSizeT;
699696 using size_type = std::size_t ;
700697 using hasher = Hash;
701- using iterator = typename std::conditional<has_value<T>::value,
702- array_hash_iterator_with_value<false >,
703- array_hash_iterator_without_value<false >>::type;
704- using const_iterator = typename std::conditional<has_value<T>::value,
705- array_hash_iterator_with_value<true >,
706- array_hash_iterator_without_value<true >>::type;
707-
708-
709-
698+ using iterator = array_hash_iterator<false >;
699+ using const_iterator = array_hash_iterator<true >;
700+
701+
710702/*
711703 * Iterator classes
712704 */
713- private :
705+ public :
714706 template <bool is_const>
715707 class array_hash_iterator {
716- friend class array_hash_iterator < true > ;
708+ friend class array_hash ;
717709
718- protected :
710+ private :
719711 using iterator_array_bucket = typename array_bucket::const_iterator;
720712
721713 using iterator_buckets = typename std::conditional<is_const,
@@ -726,7 +718,20 @@ class array_hash : private value_container<T>, private Hash, private GrowthPolic
726718 const array_hash*,
727719 array_hash*>::type;
728720
729- protected:
721+ public:
722+ using iterator_category = std::forward_iterator_tag;
723+ using value_type = typename std::conditional<has_value<T>::value, T, void >::type;
724+ using difference_type = std::ptrdiff_t ;
725+ using reference = typename std::conditional<has_value<T>::value,
726+ typename std::conditional<is_const, typename std::add_lvalue_reference<const T>::type,
727+ typename std::add_lvalue_reference<T>::type>::type,
728+ void >::type;
729+ using pointer = typename std::conditional<has_value<T>::value,
730+ typename std::conditional<is_const, const T*, T*>::type,
731+ void >::type;
732+
733+
734+ private:
730735 array_hash_iterator (iterator_buckets buckets_iterator, iterator_array_bucket array_bucket_iterator,
731736 array_hash_ptr array_hash_p) noexcept :
732737 m_buckets_iterator (buckets_iterator),
@@ -754,6 +759,27 @@ class array_hash : private value_container<T>, private Hash, private GrowthPolic
754759 return m_array_bucket_iterator.key_size ();
755760 }
756761
762+ #ifdef TSL_HAS_STRING_VIEW
763+ std::basic_string_view<CharT, Traits> key_sv () const {
764+ return std::basic_string_view<CharT, Traits>(key (), key_size ());
765+ }
766+ #endif
767+
768+ template <class U = T, typename std::enable_if<has_value<U>::value>::type* = nullptr >
769+ reference value () const {
770+ return this ->m_array_hash ->m_values [this ->m_array_bucket_iterator .value ()];
771+ }
772+
773+ template <class U = T, typename std::enable_if<has_value<U>::value>::type* = nullptr >
774+ reference operator *() const {
775+ return value ();
776+ }
777+
778+ template <class U = T, typename std::enable_if<has_value<U>::value>::type* = nullptr >
779+ pointer operator ->() const {
780+ return std::addressof (value ());
781+ }
782+
757783 array_hash_iterator& operator ++() {
758784 tsl_assert (m_buckets_iterator != m_array_hash->m_buckets .end ());
759785
@@ -789,152 +815,21 @@ class array_hash : private value_container<T>, private Hash, private GrowthPolic
789815 return !(lhs == rhs);
790816 }
791817
792- protected:
793- iterator_buckets m_buckets_iterator;
794- iterator_array_bucket m_array_bucket_iterator;
795-
796- array_hash_ptr m_array_hash;
797- };
798-
799- public:
800- template <bool is_const>
801- class array_hash_iterator_with_value : private array_hash_iterator <is_const> {
802- using base = array_hash_iterator<is_const>;
803- friend class array_hash ;
804-
805- array_hash_iterator_with_value (typename base::iterator_buckets buckets_iterator,
806- typename base::iterator_array_bucket array_bucket_iterator,
807- typename base::array_hash_ptr array_hash_p) noexcept :
808- base (buckets_iterator, array_bucket_iterator, array_hash_p)
809- {
810- }
811-
812- public:
813- using iterator_category = std::forward_iterator_tag;
814- using value_type = T;
815- using difference_type = std::ptrdiff_t ;
816- using reference = typename std::conditional<is_const, const T&, T&>::type;
817- using pointer = typename std::conditional<is_const, const T*, T*>::type;
818-
819- array_hash_iterator_with_value () noexcept {
820- }
821-
822- array_hash_iterator_with_value (const array_hash_iterator_with_value<false >& other) noexcept : base(other) {
823- }
824-
825- const CharT* key () const {
826- return base::key ();
827- }
828-
829- size_type key_size () const {
830- return base::key_size ();
831- }
832-
833- #ifdef TSL_HAS_STRING_VIEW
834- std::basic_string_view<CharT, Traits> key_sv () const {
835- return std::basic_string_view<CharT, Traits>(key (), key_size ());
836- }
837- #endif
838-
839- reference value () const {
840- return this ->m_array_hash ->m_values [this ->m_array_bucket_iterator .value ()];
841- }
842-
843- reference operator *() const {
844- return value ();
845- }
846-
847- pointer operator ->() const {
848- return std::addressof (value ());
849- }
850-
851- array_hash_iterator_with_value& operator ++() {
852- base::operator ++();
853- return *this ;
854- }
855-
856- array_hash_iterator_with_value operator ++(int ) {
857- return base::operator ++(0 );
858- }
859-
860- friend bool operator ==(const array_hash_iterator_with_value& lhs, const array_hash_iterator_with_value& rhs) {
861- return static_cast <base>(lhs) == static_cast <base>(rhs);
862- }
863-
864- friend bool operator !=(const array_hash_iterator_with_value& lhs, const array_hash_iterator_with_value& rhs) {
865- return !(lhs == rhs);
866- }
867-
868- protected:
818+ private:
819+ template <class U = T, typename std::enable_if<has_value<U>::value>::type* = nullptr >
869820 array_bucket_value_type value_position () const {
870821 return this ->m_array_bucket_iterator .value ();
871822 }
872- };
873-
874-
875- template <bool is_const>
876- class array_hash_iterator_without_value : private array_hash_iterator <is_const> {
877- using base = array_hash_iterator<is_const>;
878- friend class array_hash ;
879-
880- array_hash_iterator_without_value (typename base::iterator_buckets buckets_iterator,
881- typename base::iterator_array_bucket array_bucket_iterator,
882- typename base::array_hash_ptr array_hash_p) noexcept :
883- base (buckets_iterator, array_bucket_iterator, array_hash_p)
884- {
885- }
886-
887- public:
888- using iterator_category = std::forward_iterator_tag;
889- using value_type = void ;
890- using difference_type = std::ptrdiff_t ;
891- using reference = void ;
892- using pointer = void ;
893-
894- array_hash_iterator_without_value () noexcept {
895- }
896-
897- array_hash_iterator_without_value (const array_hash_iterator_without_value<false >& other) noexcept : base(other) {
898- }
899-
900- const CharT* key () const {
901- return base::key ();
902- }
903-
904- size_type key_size () const {
905- return base::key_size ();
906- }
907-
908- #ifdef TSL_HAS_STRING_VIEW
909- std::basic_string_view<CharT, Traits> key_sv () const {
910- return std::basic_string_view<CharT, Traits>(key (), key_size ());
911- }
912- #endif
913823
914- array_hash_iterator_without_value& operator ++() {
915- base::operator ++();
916- return *this ;
917- }
918-
919- array_hash_iterator_without_value operator ++(int ) {
920- return base::operator ++(0 );
921- }
922-
923- friend bool operator ==(const array_hash_iterator_without_value& lhs, const array_hash_iterator_without_value& rhs) {
924- return static_cast <base>(lhs) == static_cast <base>(rhs);
925- }
824+ private:
825+ iterator_buckets m_buckets_iterator;
826+ iterator_array_bucket m_array_bucket_iterator;
926827
927- friend bool operator !=(const array_hash_iterator_without_value& lhs, const array_hash_iterator_without_value& rhs) {
928- return !(lhs == rhs);
929- }
828+ array_hash_ptr m_array_hash;
930829 };
931830
932831
933832
934-
935-
936-
937-
938833public:
939834 array_hash (size_type bucket_count,
940835 const Hash& hash,
0 commit comments