@@ -3498,39 +3498,39 @@ namespace cpplinq
34983498
34993499 // -------------------------------------------------------------------------
35003500
3501- template <typename TKeyPredicate >
3501+ template <typename KeySelector >
35023502 struct to_map_builder : base_builder
35033503 {
3504- static TKeyPredicate get_key_predicate ();
3504+ static KeySelector get_key_selector ();
35053505
3506- typedef to_map_builder<TKeyPredicate > this_type ;
3507- typedef TKeyPredicate key_predicate_type ;
3506+ typedef to_map_builder<KeySelector > this_type ;
3507+ typedef KeySelector key_selector_type ;
35083508
3509- key_predicate_type key_predicate ;
3509+ key_selector_type key_selector ;
35103510
3511- CPPLINQ_INLINEMETHOD explicit to_map_builder (key_predicate_type key_predicate ) CPPLINQ_NOEXCEPT
3512- : key_predicate (std::move (key_predicate ))
3511+ CPPLINQ_INLINEMETHOD explicit to_map_builder (key_selector_type key_selector ) CPPLINQ_NOEXCEPT
3512+ : key_selector (std::move (key_selector ))
35133513 {
35143514 }
35153515
35163516 CPPLINQ_INLINEMETHOD to_map_builder (to_map_builder const & v)
3517- : key_predicate (v.key_predicate )
3517+ : key_selector (v.key_selector )
35183518 {
35193519 }
35203520
35213521 CPPLINQ_INLINEMETHOD to_map_builder (to_map_builder && v) CPPLINQ_NOEXCEPT
3522- : key_predicate (std::move (v.key_predicate ))
3522+ : key_selector (std::move (v.key_selector ))
35233523 {
35243524 }
35253525
35263526 template <typename TRange>
35273527 CPPLINQ_METHOD std::map<
3528- typename get_transformed_type<key_predicate_type , typename TRange::value_type>::type
3528+ typename get_transformed_type<key_selector_type , typename TRange::value_type>::type
35293529 , typename TRange::value_type
35303530 > build (TRange range) const
35313531 {
35323532 typedef std::map<
3533- typename get_transformed_type<key_predicate_type , typename TRange::value_type>::type
3533+ typename get_transformed_type<key_selector_type , typename TRange::value_type>::type
35343534 , typename TRange::value_type
35353535 > result_type;
35363536
@@ -3539,7 +3539,7 @@ namespace cpplinq
35393539 while (range.next ())
35403540 {
35413541 auto v = range.front ();
3542- auto k = key_predicate (v);
3542+ auto k = key_selector (v);
35433543
35443544 result.insert (typename result_type::value_type (std::move (k), std::move (v)));
35453545 }
@@ -3560,6 +3560,7 @@ namespace cpplinq
35603560 typedef std::vector<std::pair<key_type, size_type>> keys_type ;
35613561 typedef std::vector<value_type> values_type ;
35623562
3563+ typedef typename keys_type::const_iterator keys_iterator_type ;
35633564 typedef typename values_type::const_iterator values_iterator_type;
35643565
35653566 template <typename TRange, typename TSelector>
@@ -3627,6 +3628,71 @@ namespace cpplinq
36273628 }
36283629 }
36293630
3631+ template <typename TRange, typename TKeySelector, typename TValueSelector>
3632+ CPPLINQ_METHOD lookup (size_type capacity, TRange range, TKeySelector key_selector, TValueSelector value_selector)
3633+ {
3634+ keys_type k;
3635+ values_type v;
3636+ k.reserve (capacity);
3637+ v.reserve (capacity);
3638+
3639+ auto index = 0U ;
3640+ while (range.next ())
3641+ {
3642+ auto value = range.front ();
3643+ auto key = key_selector (value);
3644+ v.push_back (value_selector (value));
3645+ k.push_back (typename keys_type::value_type (std::move (key), index));
3646+ ++index;
3647+ }
3648+
3649+ if (v.size () == 0 )
3650+ {
3651+ return ;
3652+ }
3653+
3654+ std::sort (
3655+ k.begin ()
3656+ , k.end ()
3657+ , [] (typename keys_type::value_type const & l, typename keys_type::value_type const & r)
3658+ {
3659+ return l.first < r.first ;
3660+ }
3661+ );
3662+
3663+ keys.reserve (k.size ());
3664+ values.reserve (v.size ());
3665+
3666+ auto iter = k.begin ();
3667+ auto end = k.end ();
3668+
3669+ index = 0U ;
3670+
3671+ if (iter != end)
3672+ {
3673+ values.push_back (std::move (v[iter->second ]));
3674+ keys.push_back (typename keys_type::value_type (iter->first , index));
3675+ }
3676+
3677+ auto previous = iter;
3678+ ++iter;
3679+ ++index;
3680+
3681+ while (iter != end)
3682+ {
3683+ values.push_back (v[iter->second ]);
3684+
3685+ if (previous->first < iter->first )
3686+ {
3687+ keys.push_back (typename keys_type::value_type (iter->first , index));
3688+ }
3689+
3690+ previous = iter;
3691+ ++iter;
3692+ ++index;
3693+ }
3694+ }
3695+
36303696 CPPLINQ_INLINEMETHOD lookup (lookup const & v)
36313697 : values (v.values)
36323698 , keys (v.keys)
@@ -3806,6 +3872,14 @@ namespace cpplinq
38063872 return values.size ();
38073873 }
38083874
3875+ CPPLINQ_INLINEMETHOD from_range<keys_iterator_type> range_of_keys () const CPPLINQ_NOEXCEPT
3876+ {
3877+ return from_range<keys_iterator_type> (
3878+ keys.begin ()
3879+ , keys.end ()
3880+ );
3881+ }
3882+
38093883 CPPLINQ_INLINEMETHOD from_range<values_iterator_type> range_of_values () const CPPLINQ_NOEXCEPT
38103884 {
38113885 return from_range<values_iterator_type> (
@@ -3819,43 +3893,87 @@ namespace cpplinq
38193893 keys_type keys ;
38203894 };
38213895
3822- template <typename TKeyPredicate >
3896+ template <typename TKeySelector >
38233897 struct to_lookup_builder : base_builder
38243898 {
3825- static TKeyPredicate get_key_predicate ();
3899+ typedef to_lookup_builder<TKeySelector> this_type ;
3900+ typedef TKeySelector key_selector_type ;
38263901
3827- typedef to_lookup_builder<TKeyPredicate> this_type ;
3828- typedef TKeyPredicate key_predicate_type ;
3902+ key_selector_type key_selector ;
38293903
3830- key_predicate_type key_predicate ;
3831-
3832- CPPLINQ_INLINEMETHOD explicit to_lookup_builder (key_predicate_type key_predicate) CPPLINQ_NOEXCEPT
3833- : key_predicate (std::move (key_predicate))
3904+ CPPLINQ_INLINEMETHOD explicit to_lookup_builder (key_selector_type key_selector) CPPLINQ_NOEXCEPT
3905+ : key_selector (std::move (key_selector))
38343906 {
38353907 }
38363908
38373909 CPPLINQ_INLINEMETHOD to_lookup_builder (to_lookup_builder const & v)
3838- : key_predicate (v.key_predicate )
3910+ : key_selector (v.key_selector )
38393911 {
38403912 }
38413913
38423914 CPPLINQ_INLINEMETHOD to_lookup_builder (to_lookup_builder && v) CPPLINQ_NOEXCEPT
3843- : key_predicate (std::move (v.key_predicate ))
3915+ : key_selector (std::move (v.key_selector ))
38443916 {
38453917 }
38463918
38473919 template <typename TRange>
38483920 CPPLINQ_INLINEMETHOD lookup<
3849- typename get_transformed_type<key_predicate_type , typename TRange::value_type>::type
3921+ typename get_transformed_type<key_selector_type , typename TRange::value_type>::type
38503922 , typename TRange::value_type
38513923 > build (TRange range) const
38523924 {
38533925 typedef lookup<
3854- typename get_transformed_type<key_predicate_type , typename TRange::value_type>::type
3926+ typename get_transformed_type<key_selector_type , typename TRange::value_type>::type
38553927 , typename TRange::value_type
38563928 > result_type;
38573929
3858- result_type result (16U , range, key_predicate);
3930+ result_type result (16U , range, key_selector);
3931+
3932+ return result;
3933+ }
3934+
3935+ };
3936+
3937+ template <typename TKeySelector, typename TValueSelector>
3938+ struct to_lookup_value_selector_builder : base_builder
3939+ {
3940+ typedef to_lookup_value_selector_builder<TKeySelector, TValueSelector> this_type ;
3941+ typedef TKeySelector key_selector_type ;
3942+ typedef TValueSelector value_selector_type ;
3943+
3944+ key_selector_type key_selector ;
3945+ value_selector_type value_selector ;
3946+
3947+ CPPLINQ_INLINEMETHOD explicit to_lookup_value_selector_builder (key_selector_type key_selector, value_selector_type value_selector) CPPLINQ_NOEXCEPT
3948+ : key_selector (std::move (key_selector))
3949+ , value_selector (std::move (value_selector))
3950+ {
3951+ }
3952+
3953+ CPPLINQ_INLINEMETHOD to_lookup_value_selector_builder (to_lookup_value_selector_builder const & v)
3954+ : key_selector (v.key_selector)
3955+ : value_selector (v.value_selector)
3956+ {
3957+ }
3958+
3959+ CPPLINQ_INLINEMETHOD to_lookup_value_selector_builder (to_lookup_value_selector_builder && v) CPPLINQ_NOEXCEPT
3960+ : key_selector (std::move (v.key_selector))
3961+ , value_selector (std::move (v.value_selector))
3962+ {
3963+ }
3964+
3965+ template <typename TRange>
3966+ CPPLINQ_INLINEMETHOD lookup<
3967+ typename get_transformed_type<key_selector_type, typename TRange::value_type>::type
3968+ , typename get_transformed_type<value_selector_type, typename TRange::value_type>::type
3969+ > build (TRange range) const
3970+ {
3971+ typedef lookup<
3972+ typename get_transformed_type<key_selector_type, typename TRange::value_type>::type
3973+ , typename get_transformed_type<value_selector_type, typename TRange::value_type>::type
3974+ > result_type;
3975+
3976+ result_type result (16U , range, key_selector, value_selector);
38593977
38603978 return result;
38613979 }
@@ -5777,16 +5895,22 @@ namespace cpplinq
57775895 return detail::to_list_builder ();
57785896 }
57795897
5780- template <typename TKeyPredicate>
5781- CPPLINQ_INLINEMETHOD detail::to_map_builder<TKeyPredicate> to_map (TKeyPredicate key_predicate) CPPLINQ_NOEXCEPT
5898+ template <typename TKeySelector>
5899+ CPPLINQ_INLINEMETHOD detail::to_map_builder<TKeySelector> to_map (TKeySelector key_selector) CPPLINQ_NOEXCEPT
5900+ {
5901+ return detail::to_map_builder<TKeySelector>(std::move (key_selector));
5902+ }
5903+
5904+ template <typename TKeySelector>
5905+ CPPLINQ_INLINEMETHOD detail::to_lookup_builder<TKeySelector> to_lookup (TKeySelector key_selector) CPPLINQ_NOEXCEPT
57825906 {
5783- return detail::to_map_builder<TKeyPredicate >(std::move (key_predicate ));
5907+ return detail::to_lookup_builder<TKeySelector >(std::move (key_selector ));
57845908 }
57855909
5786- template <typename TKeyPredicate >
5787- CPPLINQ_INLINEMETHOD detail::to_lookup_builder<TKeyPredicate > to_lookup (TKeyPredicate key_predicate ) CPPLINQ_NOEXCEPT
5910+ template <typename TKeySelector, typename TValueSelector >
5911+ CPPLINQ_INLINEMETHOD detail::to_lookup_value_selector_builder<TKeySelector, TValueSelector > to_lookup (TKeySelector key_selector, TValueSelector value_selector ) CPPLINQ_NOEXCEPT
57885912 {
5789- return detail::to_lookup_builder<TKeyPredicate >(std::move (key_predicate ));
5913+ return detail::to_lookup_value_selector_builder<TKeySelector, TValueSelector >(std::move (key_selector), std::move (value_selector ));
57905914 }
57915915
57925916 // Equality operators
0 commit comments