Skip to content

Commit 675e728

Browse files
committed
Added to_lookup operator with value selector
Added range_of_keys method to lookup_range so that keys can also be iterated
1 parent 9ac1493 commit 675e728

2 files changed

Lines changed: 321 additions & 32 deletions

File tree

CppLinq/cpplinq.hpp

Lines changed: 155 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)