diff options
-rw-r--r-- | base/base_tests/stl_helpers_test.cpp | 121 | ||||
-rw-r--r-- | base/internal/message.hpp | 6 | ||||
-rw-r--r-- | base/stl_helpers.hpp | 31 |
3 files changed, 89 insertions, 69 deletions
diff --git a/base/base_tests/stl_helpers_test.cpp b/base/base_tests/stl_helpers_test.cpp index af47c7e5fb..029df6af98 100644 --- a/base/base_tests/stl_helpers_test.cpp +++ b/base/base_tests/stl_helpers_test.cpp @@ -3,6 +3,7 @@ #include "base/stl_helpers.hpp" #include "std/algorithm.hpp" +#include "std/deque.hpp" #include "std/utility.hpp" #include "std/vector.hpp" @@ -19,95 +20,109 @@ private: int m_v; }; -UNIT_TEST(LessBy) +template <template <typename...> class Cont> +void TestSortUnique() { { - using TValue = pair<int, int>; - - vector<TValue> v = {{2, 2}, {0, 4}, {3, 1}, {4, 0}, {1, 3}}; - sort(v.begin(), v.end(), my::LessBy(&TValue::first)); - for (size_t i = 0; i < v.size(); ++i) - TEST_EQUAL(i, v[i].first, ()); + Cont<int> actual = {1, 2, 1, 4, 3, 5, 2, 7, 1}; + my::SortUnique(actual); + Cont<int> const expected = {1, 2, 3, 4, 5, 7}; + TEST_EQUAL(actual, expected, ()); + } + { + using Value = int; + using Pair = pair<Value, int>; + Cont<Pair> d = + {{1, 22}, {2, 33}, {1, 23}, {4, 54}, {3, 34}, {5, 23}, {2, 23}, {7, 32}, {1, 12}}; - vector<TValue const *> pv; - for (auto const & p : v) - pv.push_back(&p); + my::SortUnique(d, my::LessBy(&Pair::first), my::EqualsBy(&Pair::first)); - sort(pv.begin(), pv.end(), my::LessBy(&TValue::second)); - for (size_t i = 0; i < pv.size(); ++i) - TEST_EQUAL(i, pv[i]->second, ()); + Cont<Value> const expected = {1, 2, 3, 4, 5, 7}; + TEST_EQUAL(d.size(), expected.size(), ()); + for (size_t i = 0; i < d.size(); ++i) + TEST_EQUAL(d[i].first, expected[i], (i)); } - { - vector<Int> v; - for (int i = 9; i >= 0; --i) - v.emplace_back(i); + using Value = double; + using Pair = pair<Value, int>; + Cont<Pair> d = + {{0.5, 11}, {1000.99, 234}, {0.5, 23}, {1234.56789, 54}, {1000.99, 34}}; - sort(v.begin(), v.end(), my::LessBy(&Int::Get)); - for (size_t i = 0; i < v.size(); ++i) - TEST_EQUAL(v[i].Get(), static_cast<int>(i), ()); + my::SortUnique(d, my::LessBy(&Pair::first), my::EqualsBy(&Pair::first)); + + Cont<Value> const expected = {0.5, 1000.99, 1234.56789}; + TEST_EQUAL(d.size(), expected.size(), ()); + for (size_t i = 0; i < d.size(); ++i) + TEST_EQUAL(d[i].first, expected[i], (i)); } } -UNIT_TEST(EqualsBy) +template <template <typename...> class Cont> +void TestEqualsBy() { { - using TValue = pair<int, int>; - vector<TValue> actual = {{1, 2}, {1, 3}, {2, 100}, {3, 7}, {3, 8}, {2, 500}}; - actual.erase(unique(actual.begin(), actual.end(), my::EqualsBy(&TValue::first)), actual.end()); + using Value = pair<int, int>; + Cont<Value> actual = {{1, 2}, {1, 3}, {2, 100}, {3, 7}, {3, 8}, {2, 500}}; + actual.erase(unique(actual.begin(), actual.end(), my::EqualsBy(&Value::first)), actual.end()); - vector<int> const expected = {{1, 2, 3, 2}}; + Cont<int> const expected = {{1, 2, 3, 2}}; TEST_EQUAL(expected.size(), actual.size(), ()); for (size_t i = 0; i < actual.size(); ++i) TEST_EQUAL(expected[i], actual[i].first, ()); } { - vector<Int> actual; + Cont<Int> actual; for (auto const v : {0, 0, 1, 2, 2, 0}) actual.emplace_back(v); actual.erase(unique(actual.begin(), actual.end(), my::EqualsBy(&Int::Get)), actual.end()); - vector<int> const expected = {{0, 1, 2, 0}}; + Cont<int> const expected = {{0, 1, 2, 0}}; TEST_EQUAL(expected.size(), actual.size(), ()); for (size_t i = 0; i < actual.size(); ++i) TEST_EQUAL(expected[i], actual[i].Get(), ()); } } -UNIT_TEST(SortUnique) +UNIT_TEST(LessBy) { { - vector<int> actual = {1, 2, 1, 4, 3, 5, 2, 7, 1}; - my::SortUnique(actual); - vector<int> const expected = {1, 2, 3, 4, 5, 7}; - TEST_EQUAL(actual, expected, ()); - } - { - using TValue = int; - using TPair = pair<TValue, int>; - vector<TPair> v = - {{1, 22}, {2, 33}, {1, 23}, {4, 54}, {3, 34}, {5, 23}, {2, 23}, {7, 32}, {1, 12}}; + using Value = pair<int, int>; - my::SortUnique<TPair>(v, my::LessBy(&TPair::first), my::EqualsBy(&TPair::first)); + vector<Value> v = {{2, 2}, {0, 4}, {3, 1}, {4, 0}, {1, 3}}; + sort(v.begin(), v.end(), my::LessBy(&Value::first)); + for (size_t i = 0; i < v.size(); ++i) + TEST_EQUAL(i, v[i].first, ()); - vector<TValue> const expected = {1, 2, 3, 4, 5, 7}; - TEST_EQUAL(v.size(), expected.size(), ()); - for (int i = 0; i < v.size(); ++i) - TEST_EQUAL(v[i].first, expected[i], (i)); + vector<Value const *> pv; + for (auto const & p : v) + pv.push_back(&p); + + sort(pv.begin(), pv.end(), my::LessBy(&Value::second)); + for (size_t i = 0; i < pv.size(); ++i) + TEST_EQUAL(i, pv[i]->second, ()); } - { - using TValue = double; - using TPair = pair<TValue, int>; - vector<TPair> v = - {{0.5, 11}, {1000.99, 234}, {0.5, 23}, {1234.56789, 54}, {1000.99, 34}}; - my::SortUnique<TPair>(v, my::LessBy(&TPair::first), my::EqualsBy(&TPair::first)); + { + vector<Int> v; + for (int i = 9; i >= 0; --i) + v.emplace_back(i); - vector<TValue> const expected = {0.5, 1000.99, 1234.56789}; - TEST_EQUAL(v.size(), expected.size(), ()); - for (int i = 0; i < v.size(); ++i) - TEST_EQUAL(v[i].first, expected[i], (i)); + sort(v.begin(), v.end(), my::LessBy(&Int::Get)); + for (size_t i = 0; i < v.size(); ++i) + TEST_EQUAL(v[i].Get(), static_cast<int>(i), ()); } } + +UNIT_TEST(EqualsBy_VectorTest) +{ + TestEqualsBy<vector>(); + TestEqualsBy<deque>(); +} + +UNIT_TEST(SortUnique_VectorTest) +{ + TestSortUnique<vector>(); + TestSortUnique<deque>(); +} } // namespace diff --git a/base/internal/message.hpp b/base/internal/message.hpp index ee6487b9cd..f9775a9a15 100644 --- a/base/internal/message.hpp +++ b/base/internal/message.hpp @@ -1,5 +1,6 @@ #pragma once #include "std/array.hpp" +#include "std/deque.hpp" #include "std/functional.hpp" #include "std/initializer_list.hpp" #include "std/iterator.hpp" @@ -100,6 +101,11 @@ template <typename T> inline string DebugPrint(vector<T> const & v) return ::my::impl::DebugPrintSequence(v.begin(), v.end()); } +template <typename T> inline string DebugPrint(deque<T> const & d) +{ + return ::my::impl::DebugPrintSequence(d.begin(), d.end()); +} + template <typename T> inline string DebugPrint(list<T> const & v) { return ::my::impl::DebugPrintSequence(v.begin(), v.end()); diff --git a/base/stl_helpers.hpp b/base/stl_helpers.hpp index 0121e12613..3a667766de 100644 --- a/base/stl_helpers.hpp +++ b/base/stl_helpers.hpp @@ -5,7 +5,6 @@ #include "std/utility.hpp" #include "std/vector.hpp" - namespace my { namespace impl @@ -80,28 +79,28 @@ struct Equals<false, T, C> }; } // namespace impl -// Sorts and removes duplicate entries from |v|. -template <typename T> -void SortUnique(vector<T> & v) +// Sorts and removes duplicate entries from |c|. +template <typename Cont> +void SortUnique(Cont & c) { - sort(v.begin(), v.end()); - v.erase(unique(v.begin(), v.end()), v.end()); + sort(c.begin(), c.end()); + c.erase(unique(c.begin(), c.end()), c.end()); } -// Sorts according to |comp| and removes duplicate entries according to |pred| from |v|. -// Note. If several entries are equal according to |pred| an arbitrary entry of them -// is left in |v| after a call of this function. -template <typename T, typename TLess, typename TEquals> -void SortUnique(vector<T> & v, TLess && less, TEquals && equals) +// Sorts according to |less| and removes duplicate entries according to |equals| from |c|. +// Note. If several entries are equal according to |less| an arbitrary entry of them +// is left in |c| after a call of this function. +template <class Cont, typename Less, typename Equals> +void SortUnique(Cont & c, Less && less, Equals && equals) { - sort(v.begin(), v.end(), forward<TLess>(less)); - v.erase(unique(v.begin(), v.end(), forward<TEquals>(equals)), v.end()); + sort(c.begin(), c.end(), forward<Less>(less)); + c.erase(unique(c.begin(), c.end(), forward<Equals>(equals)), c.end()); } -template <typename T, class TFn> -void EraseIf(vector<T> & v, TFn && fn) +template <class Cont, class Fn> +void EraseIf(Cont & c, Fn && fn) { - v.erase(remove_if(v.begin(), v.end(), forward<TFn>(fn)), v.end()); + c.erase(remove_if(c.begin(), c.end(), forward<Fn>(fn)), c.end()); } // Creates a comparer being able to compare two instances of class C |