diff options
author | Yuri Gorshenin <y@maps.me> | 2016-03-11 17:44:01 +0300 |
---|---|---|
committer | Sergey Yershov <yershov@corp.mail.ru> | 2016-03-23 16:53:01 +0300 |
commit | 575d9eb26d3870b94be38cba5abb48c33b33a45f (patch) | |
tree | e242f4e75313991dc0a54f1d21358c29a87c28ab /base | |
parent | bc44c63d03d32c8f77c9f208f38b8df443a07130 (diff) |
[search] Used linear model for rank calculation.
Diffstat (limited to 'base')
-rw-r--r-- | base/base_tests/stl_helpers_test.cpp | 27 | ||||
-rw-r--r-- | base/stl_helpers.hpp | 32 |
2 files changed, 54 insertions, 5 deletions
diff --git a/base/base_tests/stl_helpers_test.cpp b/base/base_tests/stl_helpers_test.cpp index 00b59ab302..7d23bdd3d2 100644 --- a/base/base_tests/stl_helpers_test.cpp +++ b/base/base_tests/stl_helpers_test.cpp @@ -6,7 +6,20 @@ #include "std/utility.hpp" #include "std/vector.hpp" -UNIT_TEST(CompareBy_Smoke) +namespace +{ +class Int +{ +public: + explicit Int(int v) : m_v(v) {} + + inline int Get() const { return m_v; } + +private: + int m_v; +}; + +UNIT_TEST(CompareBy_Field) { vector<pair<int, int>> v = {{2, 2}, {0, 4}, {3, 1}, {4, 0}, {1, 3}}; sort(v.begin(), v.end(), my::CompareBy(&pair<int, int>::first)); @@ -21,3 +34,15 @@ UNIT_TEST(CompareBy_Smoke) for (size_t i = 0; i < pv.size(); ++i) TEST_EQUAL(i, pv[i]->second, ()); } + +UNIT_TEST(CompareBy_Method) +{ + vector<Int> v; + for (int i = 9; i >= 0; --i) + v.emplace_back(i); + + sort(v.begin(), v.end(), my::CompareBy(&Int::Get)); + for (size_t i = 0; i < v.size(); ++i) + TEST_EQUAL(v[i].Get(), static_cast<int>(i), ()); +} +} // namespace diff --git a/base/stl_helpers.hpp b/base/stl_helpers.hpp index 7dcc4f5beb..916989a040 100644 --- a/base/stl_helpers.hpp +++ b/base/stl_helpers.hpp @@ -7,8 +7,11 @@ namespace my { namespace impl { -template <typename T, typename C> -struct Comparer +template <bool isField, typename T, typename C> +struct Comparer; + +template<typename T, typename C> +struct Comparer<true, T, C> { Comparer(T(C::*p)) : p_(p) {} @@ -21,6 +24,21 @@ struct Comparer T(C::*p_); }; + +template<typename T, typename C> +struct Comparer<false, T, C> +{ + Comparer(T (C::*p)() const) : p_(p) {} + + inline bool operator()(C const & lhs, C const & rhs) const { return (lhs.*p_)() < (rhs.*p_)(); } + + inline bool operator()(C const * const lhs, C const * const rhs) const + { + return (lhs->*p_)() < (rhs->*p_)(); + } + + T(C::*p_)() const; +}; } // namespace impl // Sorts and removes duplicate entries from |v|. @@ -36,8 +54,14 @@ void SortUnique(std::vector<T> & v) // create comparer that is able to compare pairs of ints by second // component, it's enough to call CompareBy(&pair<int, int>::second). template <typename T, typename C> -impl::Comparer<T, C> CompareBy(T(C::*p)) +impl::Comparer<true, T, C> CompareBy(T(C::*p)) +{ + return impl::Comparer<true, T, C>(p); +} + +template <typename T, typename C> +impl::Comparer<false, T, C> CompareBy(T (C::*p)() const) { - return impl::Comparer<T, C>(p); + return impl::Comparer<false, T, C>(p); } } // namespace my |