Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/base
diff options
context:
space:
mode:
authorMaxim Pimenov <m@maps.me>2018-09-12 14:22:15 +0300
committerVlad Mihaylenko <vxmihaylenko@gmail.com>2018-09-14 15:14:36 +0300
commitc7e09657fa5cc6fd5600252b41e9774b83c0a45d (patch)
tree0c1636a81a6afba6ae87b3040096bb86bf862c81 /base
parent4a44e1d009cf30dbb9fe759260aeef221a7be561 (diff)
[base] Unified stl_add and stl_helpers.
Diffstat (limited to 'base')
-rw-r--r--base/CMakeLists.txt1
-rw-r--r--base/base_tests/CMakeLists.txt3
-rw-r--r--base/base_tests/cache_test.cpp5
-rw-r--r--base/base_tests/regexp_test.cpp14
-rw-r--r--base/base_tests/stl_helpers_test.cpp152
-rw-r--r--base/base_tests/stl_helpers_tests.cpp (renamed from base/base_tests/stl_add_test.cpp)161
-rw-r--r--base/levenshtein_dfa.cpp4
-rw-r--r--base/stl_add.hpp246
-rw-r--r--base/stl_helpers.hpp245
-rw-r--r--base/string_utils.hpp4
10 files changed, 396 insertions, 439 deletions
diff --git a/base/CMakeLists.txt b/base/CMakeLists.txt
index 0c97898372..1365ea8f88 100644
--- a/base/CMakeLists.txt
+++ b/base/CMakeLists.txt
@@ -63,7 +63,6 @@ set(
src_point.cpp
src_point.hpp
stats.hpp
- stl_add.hpp
stl_helpers.hpp
stl_iterator.hpp
string_format.cpp
diff --git a/base/base_tests/CMakeLists.txt b/base/base_tests/CMakeLists.txt
index 56257580aa..500b9cae61 100644
--- a/base/base_tests/CMakeLists.txt
+++ b/base/base_tests/CMakeLists.txt
@@ -30,8 +30,7 @@ set(
rolling_hash_test.cpp
scope_guard_test.cpp
small_set_test.cpp
- stl_add_test.cpp
- stl_helpers_test.cpp
+ stl_helpers_tests.cpp
string_format_test.cpp
string_utils_test.cpp
suffix_array_tests.cpp
diff --git a/base/base_tests/cache_test.cpp b/base/base_tests/cache_test.cpp
index 8e9ae4dc52..5c1322b33d 100644
--- a/base/base_tests/cache_test.cpp
+++ b/base/base_tests/cache_test.cpp
@@ -1,7 +1,8 @@
#include "testing/testing.hpp"
+
#include "base/cache.hpp"
#include "base/macros.hpp"
-#include "base/stl_add.hpp"
+#include "base/stl_helpers.hpp"
#include <functional>
@@ -86,7 +87,7 @@ UNIT_TEST(CacheSmoke_0)
cache.Find(0, found);
TEST(!found, ());
std::vector<char> v;
- cache.ForEachValue(MakeBackInsertFunctor(v));
+ cache.ForEachValue(base::MakeBackInsertFunctor(v));
TEST_EQUAL(v, std::vector<char>(8, 0), ());
}
diff --git a/base/base_tests/regexp_test.cpp b/base/base_tests/regexp_test.cpp
index 06e0f2921f..6c4fa912a0 100644
--- a/base/base_tests/regexp_test.cpp
+++ b/base/base_tests/regexp_test.cpp
@@ -1,6 +1,6 @@
#include "testing/testing.hpp"
-#include "base/stl_add.hpp"
+#include "base/stl_helpers.hpp"
#include "base/string_utils.hpp"
#include <regex>
@@ -29,7 +29,7 @@ UNIT_TEST(RegExp_ForEachMatched)
{
std::string const s = "6.66, 9.99";
std::vector<std::string> v;
- strings::ForEachMatched(s, exp, MakeBackInsertFunctor(v));
+ strings::ForEachMatched(s, exp, base::MakeBackInsertFunctor(v));
TEST_EQUAL(v.size(), 1, ());
TEST_EQUAL(v[0], s, ());
}
@@ -38,7 +38,7 @@ UNIT_TEST(RegExp_ForEachMatched)
std::string const s1 = "6.66, 9.99";
std::string const s2 = "-5.55, -7.77";
std::vector<std::string> v;
- strings::ForEachMatched(s1 + " 180 , bfuewib 365@" + s2, exp, MakeBackInsertFunctor(v));
+ strings::ForEachMatched(s1 + " 180 , bfuewib 365@" + s2, exp, base::MakeBackInsertFunctor(v));
TEST_EQUAL(v.size(), 2, ());
TEST_EQUAL(v[0], s1, ());
TEST_EQUAL(v[1], s2, ());
@@ -47,7 +47,7 @@ UNIT_TEST(RegExp_ForEachMatched)
{
std::string const s = "X6.66, 9.99";
std::vector<std::string> v;
- strings::ForEachMatched(s, exp, MakeBackInsertFunctor(v));
+ strings::ForEachMatched(s, exp, base::MakeBackInsertFunctor(v));
TEST_EQUAL(v.size(), 1, ());
TEST_EQUAL(v[0], std::string(s.begin() + 1, s.end()), ());
}
@@ -55,7 +55,7 @@ UNIT_TEST(RegExp_ForEachMatched)
{
std::string const s = "6.66, 9.99X";
std::vector<std::string> v;
- strings::ForEachMatched(s, exp, MakeBackInsertFunctor(v));
+ strings::ForEachMatched(s, exp, base::MakeBackInsertFunctor(v));
TEST_EQUAL(v.size(), 1, ());
TEST_EQUAL(v[0], std::string(s.begin(), s.end() - 1), ());
}
@@ -63,14 +63,14 @@ UNIT_TEST(RegExp_ForEachMatched)
{
std::string const s = "6.66X, 9.99";
std::vector<std::string> v;
- strings::ForEachMatched(s, exp, MakeBackInsertFunctor(v));
+ strings::ForEachMatched(s, exp, base::MakeBackInsertFunctor(v));
TEST_EQUAL(v.size(), 0, ());
}
{
std::string const s = "6.66, X9.99";
std::vector<std::string> v;
- strings::ForEachMatched(s, exp, MakeBackInsertFunctor(v));
+ strings::ForEachMatched(s, exp, base::MakeBackInsertFunctor(v));
TEST_EQUAL(v.size(), 0, ());
}
}
diff --git a/base/base_tests/stl_helpers_test.cpp b/base/base_tests/stl_helpers_test.cpp
deleted file mode 100644
index 12ebe85699..0000000000
--- a/base/base_tests/stl_helpers_test.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-#include "testing/testing.hpp"
-
-#include "base/stl_helpers.hpp"
-
-#include <algorithm>
-#include <deque>
-#include <utility>
-#include <vector>
-
-namespace
-{
-class Int
-{
-public:
- explicit Int(int v) : m_v(v) {}
-
- inline int Get() const { return m_v; }
-
-private:
- int m_v;
-};
-
-template <template <typename...> class Cont>
-void TestSortUnique()
-{
- {
- 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 = std::pair<Value, int>;
- Cont<Pair> d =
- {{1, 22}, {2, 33}, {1, 23}, {4, 54}, {3, 34}, {5, 23}, {2, 23}, {7, 32}, {1, 12}};
-
- my::SortUnique(d, my::LessBy(&Pair::first), my::EqualsBy(&Pair::first));
-
- 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));
- }
- {
- using Value = double;
- using Pair = std::pair<Value, int>;
- Cont<Pair> d =
- {{0.5, 11}, {1000.99, 234}, {0.5, 23}, {1234.56789, 54}, {1000.99, 34}};
-
- 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));
- }
-}
-
-template <template <typename...> class Cont>
-void TestEqualsBy()
-{
- {
- using Value = std::pair<int, int>;
- Cont<Value> actual = {{1, 2}, {1, 3}, {2, 100}, {3, 7}, {3, 8}, {2, 500}};
- actual.erase(std::unique(actual.begin(), actual.end(), my::EqualsBy(&Value::first)), actual.end());
-
- 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, ());
- }
-
- {
- Cont<Int> actual;
- for (auto const v : {0, 0, 1, 2, 2, 0})
- actual.emplace_back(v);
- actual.erase(std::unique(actual.begin(), actual.end(), my::EqualsBy(&Int::Get)), actual.end());
-
- 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(LessBy)
-{
- {
- using Value = std::pair<int, int>;
-
- std::vector<Value> v = {{2, 2}, {0, 4}, {3, 1}, {4, 0}, {1, 3}};
- std::sort(v.begin(), v.end(), my::LessBy(&Value::first));
- for (size_t i = 0; i < v.size(); ++i)
- TEST_EQUAL(i, static_cast<size_t>(v[i].first), ());
-
- std::vector<Value const *> pv;
- for (auto const & p : v)
- pv.push_back(&p);
-
- std::sort(pv.begin(), pv.end(), my::LessBy(&Value::second));
- for (size_t i = 0; i < pv.size(); ++i)
- TEST_EQUAL(i, static_cast<size_t>(pv[i]->second), ());
- }
-
- {
- std::vector<Int> v;
- for (int i = 9; i >= 0; --i)
- v.emplace_back(i);
-
- std::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<std::vector>();
- TestEqualsBy<std::deque>();
-}
-
-UNIT_TEST(SortUnique_VectorTest)
-{
- TestSortUnique<std::vector>();
- TestSortUnique<std::deque>();
-}
-
-UNIT_TEST(IgnoreFirstArgument)
-{
- {
- int s = 0;
- auto f1 = [&](int a, int b) { s += a + b; };
- auto f2 = [&](int a, int b) { s -= a + b; };
- auto f3 = my::MakeIgnoreFirstArgument(f2);
-
- f1(2, 3);
- TEST_EQUAL(s, 5, ());
- f3(1, 2, 3);
- TEST_EQUAL(s, 0, ());
- }
-
- {
- auto f1 = [](int a, int b) -> int { return a + b; };
- auto f2 = my::MakeIgnoreFirstArgument(f1);
-
- auto const x = f1(2, 3);
- auto const y = f2("ignored", 2, 3);
- TEST_EQUAL(x, y, ());
- }
-}
-} // namespace
diff --git a/base/base_tests/stl_add_test.cpp b/base/base_tests/stl_helpers_tests.cpp
index 82ff469580..cc76540a42 100644
--- a/base/base_tests/stl_add_test.cpp
+++ b/base/base_tests/stl_helpers_tests.cpp
@@ -1,22 +1,156 @@
#include "testing/testing.hpp"
#include "base/macros.hpp"
+#include "base/stl_helpers.hpp"
-#include "base/stl_add.hpp"
-
+#include <algorithm>
#include <deque>
+#include <utility>
+#include <vector>
+
+using namespace base;
+
+namespace
+{
+class Int
+{
+public:
+ explicit Int(int v) : m_v(v) {}
+
+ inline int Get() const { return m_v; }
+
+private:
+ int m_v;
+};
+
+template <template <typename...> class Cont>
+void TestSortUnique()
+{
+ {
+ Cont<int> actual = {1, 2, 1, 4, 3, 5, 2, 7, 1};
+ SortUnique(actual);
+ Cont<int> const expected = {1, 2, 3, 4, 5, 7};
+ TEST_EQUAL(actual, expected, ());
+ }
+ {
+ using Value = int;
+ using Pair = std::pair<Value, int>;
+ Cont<Pair> d =
+ {{1, 22}, {2, 33}, {1, 23}, {4, 54}, {3, 34}, {5, 23}, {2, 23}, {7, 32}, {1, 12}};
+
+ SortUnique(d, LessBy(&Pair::first), EqualsBy(&Pair::first));
+ 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));
+ }
+ {
+ using Value = double;
+ using Pair = std::pair<Value, int>;
+ Cont<Pair> d =
+ {{0.5, 11}, {1000.99, 234}, {0.5, 23}, {1234.56789, 54}, {1000.99, 34}};
-UNIT_TEST(STLAdd_IsSorted)
+ SortUnique(d, LessBy(&Pair::first), 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));
+ }
+}
+
+template <template <typename...> class Cont>
+void TestEqualsBy()
{
- TEST(IsSorted(static_cast<int*>(0), static_cast<int*>(0)), ());
- int v1[] = { 1, 3, 5 };
- int const v2[] = { 1, 3, 2 };
- TEST(!IsSorted(&v2[0], &v2[0] + ARRAY_SIZE(v2)), ());
- TEST(IsSorted(&v1[0], &v1[0] + ARRAY_SIZE(v1)), ());
- TEST(IsSorted(&v1[0], &v1[0] + 0), ());
- TEST(IsSorted(&v1[0], &v1[0] + 1), ());
- TEST(IsSorted(&v1[0], &v1[0] + 2), ());
+ {
+ using Value = std::pair<int, int>;
+ Cont<Value> actual = {{1, 2}, {1, 3}, {2, 100}, {3, 7}, {3, 8}, {2, 500}};
+ actual.erase(std::unique(actual.begin(), actual.end(), EqualsBy(&Value::first)), actual.end());
+
+ 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, ());
+ }
+
+ {
+ Cont<Int> actual;
+ for (auto const v : {0, 0, 1, 2, 2, 0})
+ actual.emplace_back(v);
+ actual.erase(std::unique(actual.begin(), actual.end(), EqualsBy(&Int::Get)), actual.end());
+
+ 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(LessBy)
+{
+ {
+ using Value = std::pair<int, int>;
+
+ std::vector<Value> v = {{2, 2}, {0, 4}, {3, 1}, {4, 0}, {1, 3}};
+ std::sort(v.begin(), v.end(), LessBy(&Value::first));
+ for (size_t i = 0; i < v.size(); ++i)
+ TEST_EQUAL(i, static_cast<size_t>(v[i].first), ());
+
+ std::vector<Value const *> pv;
+ for (auto const & p : v)
+ pv.push_back(&p);
+
+ std::sort(pv.begin(), pv.end(), LessBy(&Value::second));
+ for (size_t i = 0; i < pv.size(); ++i)
+ TEST_EQUAL(i, static_cast<size_t>(pv[i]->second), ());
+ }
+
+ {
+ std::vector<Int> v;
+ for (int i = 9; i >= 0; --i)
+ v.emplace_back(i);
+
+ std::sort(v.begin(), v.end(), 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<std::vector>();
+ TestEqualsBy<std::deque>();
+}
+
+UNIT_TEST(SortUnique_VectorTest)
+{
+ TestSortUnique<std::vector>();
+ TestSortUnique<std::deque>();
+}
+
+UNIT_TEST(IgnoreFirstArgument)
+{
+ {
+ int s = 0;
+ auto f1 = [&](int a, int b) { s += a + b; };
+ auto f2 = [&](int a, int b) { s -= a + b; };
+ auto f3 = MakeIgnoreFirstArgument(f2);
+
+ f1(2, 3);
+ TEST_EQUAL(s, 5, ());
+ f3(1, 2, 3);
+ TEST_EQUAL(s, 0, ());
+ }
+
+ {
+ auto f1 = [](int a, int b) -> int { return a + b; };
+ auto f2 = MakeIgnoreFirstArgument(f1);
+
+ auto const x = f1(2, 3);
+ auto const y = f2("ignored", 2, 3);
+ TEST_EQUAL(x, y, ());
+ }
}
namespace
@@ -33,7 +167,7 @@ namespace
}
}
-UNIT_TEST(STLAdd_RemoveIfKeepValid)
+UNIT_TEST(RemoveIfKeepValid)
{
{
std::vector<int> v;
@@ -103,7 +237,7 @@ namespace
}
}
-UNIT_TEST(STLAdd_AccumulateIntervals)
+UNIT_TEST(AccumulateIntervals)
{
typedef std::pair<int, int> T;
size_t idTest = 0;
@@ -192,3 +326,4 @@ UNIT_TEST(STLAdd_AccumulateIntervals)
CheckAccumulateIntervals(idTest, arr1, arr2, res);
}
}
+} // namespace
diff --git a/base/levenshtein_dfa.cpp b/base/levenshtein_dfa.cpp
index b6bae3928b..9d1a5cf7b3 100644
--- a/base/levenshtein_dfa.cpp
+++ b/base/levenshtein_dfa.cpp
@@ -189,7 +189,7 @@ void LevenshteinDFA::State::Normalize()
}
m_positions.erase(m_positions.begin() + j, m_positions.end());
- my::SortUnique(m_positions);
+ base::SortUnique(m_positions);
}
// LevenshteinDFA ----------------------------------------------------------------------------------
@@ -211,7 +211,7 @@ LevenshteinDFA::LevenshteinDFA(UniString const & s, size_t prefixSize,
m_alphabet.insert(m_alphabet.end(), misprints.begin(), misprints.end());
}
}
- my::SortUnique(m_alphabet);
+ base::SortUnique(m_alphabet);
UniChar missed = 0;
for (size_t i = 0; i < m_alphabet.size() && missed >= m_alphabet[i]; ++i)
diff --git a/base/stl_add.hpp b/base/stl_add.hpp
deleted file mode 100644
index 2eb4909014..0000000000
--- a/base/stl_add.hpp
+++ /dev/null
@@ -1,246 +0,0 @@
-#pragma once
-
-#include <algorithm>
-#include <functional>
-#include <initializer_list>
-#include <iterator>
-#include <memory>
-
-namespace my
-{
-using StringIL = std::initializer_list<char const *>;
-} // namespace my
-
-template <class ContainerT> class BackInsertFunctor
-{
- ContainerT & m_Container;
-public:
- explicit BackInsertFunctor(ContainerT & container) : m_Container(container)
- {
- }
- void operator() (typename ContainerT::value_type const & t) const
- {
- m_Container.push_back(t);
- }
-};
-
-template <class ContainerT>
-BackInsertFunctor<ContainerT> MakeBackInsertFunctor(ContainerT & container)
-{
- return BackInsertFunctor<ContainerT>(container);
-}
-
-template <class ContainerT> class InsertFunctor
-{
- ContainerT & m_Container;
-public:
- explicit InsertFunctor(ContainerT & container) : m_Container(container)
- {
- }
- void operator() (typename ContainerT::value_type const & t) const
- {
- m_Container.insert(end(m_Container), t);
- }
-};
-
-template <class ContainerT>
-InsertFunctor<ContainerT> MakeInsertFunctor(ContainerT & container)
-{
- return InsertFunctor<ContainerT>(container);
-}
-
-template <class IterT, class CompareT> inline bool IsSorted(IterT beg, IterT end, CompareT comp)
-{
- if (beg == end)
- return true;
- IterT prev = beg;
- for (++beg; beg != end; ++beg, ++prev)
- {
- if (comp(*beg, *prev))
- return false;
- }
- return true;
-}
-
-template <class IterT, class CompareT>
-inline bool IsSortedAndUnique(IterT beg, IterT end, CompareT comp)
-{
- if (beg == end)
- return true;
- IterT prev = beg;
- for (++beg; beg != end; ++beg, ++prev)
- {
- if (!comp(*prev, *beg))
- return false;
- }
- return true;
-}
-
-template <class IterT, class CompareT>
-IterT RemoveIfKeepValid(IterT beg, IterT end, CompareT comp)
-{
- while (beg != end)
- {
- if (comp(*beg))
- {
- while (beg != --end)
- {
- if (!comp(*end))
- {
- std::swap(*beg, *end);
- ++beg;
- break;
- }
- }
- }
- else
- ++beg;
- }
-
- return end;
-}
-
-
-template <class IterT> inline bool IsSorted(IterT beg, IterT end)
-{
- return IsSorted(beg, end, std::less<typename std::iterator_traits<IterT>::value_type>());
-}
-
-template <class IterT> inline bool IsSortedAndUnique(IterT beg, IterT end)
-{
- return IsSortedAndUnique(beg, end, std::less<typename std::iterator_traits<IterT>::value_type>());
-}
-
-struct DeleteFunctor
-{
- template <typename T> void operator() (T const * p) const
- {
- delete p;
- }
-};
-
-namespace impl
-{
- template <class TContainer, class TDeletor> class DeleteRangeFunctor
- {
- TContainer & m_cont;
- TDeletor m_deletor;
-
- public:
- DeleteRangeFunctor(TContainer & cont, TDeletor const & deletor)
- : m_cont(cont), m_deletor(deletor)
- {
- }
-
- void operator() ()
- {
- for_each(m_cont.begin(), m_cont.end(), m_deletor);
- m_cont.clear();
- }
- };
-}
-
-template <class TContainer, class TDeletor>
-impl::DeleteRangeFunctor<TContainer, TDeletor>
-GetRangeDeletor(TContainer & cont, TDeletor const & deletor)
-{
- return impl::DeleteRangeFunctor<TContainer, TDeletor>(cont, deletor);
-}
-
-template <class TContainer, class TDeletor>
-void DeleteRange(TContainer & cont, TDeletor const & deletor)
-{
- (void)GetRangeDeletor(cont, deletor)();
-}
-
-struct IdFunctor
-{
- template <typename T> inline T operator () (T const & x) const
- {
- return x;
- }
-};
-
-template <class T> struct EqualFunctor
-{
- T const & m_t;
- explicit EqualFunctor(T const & t) : m_t(t) {}
- inline bool operator() (T const & t) const { return (t == m_t); }
-};
-
-template <typename IterT> IterT NextIterInCycle(IterT it, IterT beg, IterT end)
-{
- if (++it == end)
- return beg;
- return it;
-}
-
-template <typename IterT> IterT PrevIterInCycle(IterT it, IterT beg, IterT end)
-{
- if (it == beg)
- it = end;
- return --it;
-}
-
-template <class IterT1, class IterT2, class InsertIterT>
-void AccumulateIntervals1With2(IterT1 b1, IterT1 e1, IterT2 b2, IterT2 e2, InsertIterT res)
-{
- //typedef typename iterator_traits<InsertIterT>::value_type T;
- typedef typename std::iterator_traits<IterT1>::value_type T;
-
- T prev;
- bool validPrev = false;
-
- while (b1 != e1 || b2 != e2)
- {
- // Try to continue previous range.
- if (validPrev)
- {
- // add b1 range to prev if needed
- if (b1 != e1 && b1->first < prev.second)
- {
- // correct only second if needed
- if (prev.second < b1->second)
- prev.second = b1->second;
- ++b1;
- continue;
- }
-
- // add b2 range to prev if needed
- if (b2 != e2 && b2->first < prev.second)
- {
- // check that intervals are overlapped
- if (prev.first < b2->second)
- {
- // correct first and second if needed
- if (b2->first < prev.first)
- prev.first = b2->first;
- if (prev.second < b2->second)
- prev.second = b2->second;
- }
-
- ++b2;
- continue;
- }
-
- // if nothing to add - push to results
- *res++ = prev;
- validPrev = false;
- }
-
- if (b1 != e1)
- {
- // start new range
- prev = *b1++;
- validPrev = true;
- }
- else
- {
- // go to exit
- break;
- }
- }
-
- if (validPrev)
- *res++ = prev;
-}
diff --git a/base/stl_helpers.hpp b/base/stl_helpers.hpp
index 7296daabc9..4ad67bed8a 100644
--- a/base/stl_helpers.hpp
+++ b/base/stl_helpers.hpp
@@ -2,13 +2,18 @@
#include <algorithm>
#include <functional>
+#include <initializer_list>
+#include <iterator>
+#include <memory>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>
-namespace my
+namespace base
{
+using StringIL = std::initializer_list<char const *>;
+
namespace impl
{
// When isField is true, following functors operate on a
@@ -22,9 +27,9 @@ struct Less<true, T, C>
{
Less(T(C::*p)) : m_p(p) {}
- inline bool operator()(C const & lhs, C const & rhs) const { return lhs.*m_p < rhs.*m_p; }
+ bool operator()(C const & lhs, C const & rhs) const { return lhs.*m_p < rhs.*m_p; }
- inline bool operator()(C const * const lhs, C const * const rhs) const
+ bool operator()(C const * const lhs, C const * const rhs) const
{
return lhs->*m_p < rhs->*m_p;
}
@@ -37,9 +42,9 @@ struct Less<false, T, C>
{
Less(T (C::*p)() const) : m_p(p) {}
- inline bool operator()(C const & lhs, C const & rhs) const { return (lhs.*m_p)() < (rhs.*m_p)(); }
+ bool operator()(C const & lhs, C const & rhs) const { return (lhs.*m_p)() < (rhs.*m_p)(); }
- inline bool operator()(C const * const lhs, C const * const rhs) const
+ bool operator()(C const * const lhs, C const * const rhs) const
{
return (lhs->*m_p)() < (rhs->*m_p)();
}
@@ -55,9 +60,9 @@ struct Equals<true, T, C>
{
Equals(T(C::*p)) : m_p(p) {}
- inline bool operator()(C const & lhs, C const & rhs) const { return lhs.*m_p == rhs.*m_p; }
+ bool operator()(C const & lhs, C const & rhs) const { return lhs.*m_p == rhs.*m_p; }
- inline bool operator()(C const * const lhs, C const * const rhs) const
+ bool operator()(C const * const lhs, C const * const rhs) const
{
return lhs->*m_p == rhs->*m_p;
}
@@ -70,15 +75,34 @@ struct Equals<false, T, C>
{
Equals(T (C::*p)() const) : m_p(p) {}
- inline bool operator()(C const & lhs, C const & rhs) const { return (lhs.*m_p)() == (rhs.*m_p)(); }
+ bool operator()(C const & lhs, C const & rhs) const { return (lhs.*m_p)() == (rhs.*m_p)(); }
- inline bool operator()(C const * const lhs, C const * const rhs) const
+ bool operator()(C const * const lhs, C const * const rhs) const
{
return (lhs->*m_p)() == (rhs->*m_p)();
}
T (C::*m_p)() const;
};
+
+template <typename Container, typename Deletor>
+class DeleteRangeFunctor
+{
+public:
+ DeleteRangeFunctor(Container & cont, Deletor const & deletor) : m_cont(cont), m_deletor(deletor)
+ {
+ }
+
+ void operator()()
+ {
+ for_each(m_cont.begin(), m_cont.end(), m_deletor);
+ m_cont.clear();
+ }
+
+private:
+ Container & m_cont;
+ Deletor m_deletor;
+};
} // namespace impl
// Sorts and removes duplicate entries from |c|.
@@ -92,14 +116,14 @@ void SortUnique(Cont & c)
// 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>
+template <typename Cont, typename Less, typename Equals>
void SortUnique(Cont & c, Less && less, Equals && equals)
{
sort(c.begin(), c.end(), std::forward<Less>(less));
c.erase(unique(c.begin(), c.end(), std::forward<Equals>(equals)), c.end());
}
-template <class Cont, class Fn>
+template <typename Cont, typename Fn>
void EraseIf(Cont & c, Fn && fn)
{
c.erase(remove_if(c.begin(), c.end(), std::forward<Fn>(fn)), c.end());
@@ -193,4 +217,201 @@ for_each_in_tuple_const(std::tuple<Tp...> const & t, Fn && fn)
for_each_in_tuple_const<I + 1, Fn, Tp...>(t, std::forward<Fn>(fn));
}
-} // namespace my
+template <typename Container>
+class BackInsertFunctor
+{
+public:
+ explicit BackInsertFunctor(Container & container) : m_Container(container) {}
+ void operator()(typename Container::value_type const & t) const { m_Container.push_back(t); }
+
+private:
+ Container & m_Container;
+};
+
+template <typename Container>
+BackInsertFunctor<Container> MakeBackInsertFunctor(Container & container)
+{
+ return BackInsertFunctor<Container>(container);
+}
+
+template <typename Container>
+class InsertFunctor
+{
+public:
+ explicit InsertFunctor(Container & container) : m_Container(container) {}
+ void operator()(typename Container::value_type const & t) const
+ {
+ m_Container.insert(end(m_Container), t);
+ }
+
+private:
+ Container & m_Container;
+};
+
+template <typename Container>
+InsertFunctor<Container> MakeInsertFunctor(Container & container)
+{
+ return InsertFunctor<Container>(container);
+}
+
+template <typename Iter, typename Compare>
+bool IsSortedAndUnique(Iter beg, Iter end, Compare comp)
+{
+ if (beg == end)
+ return true;
+ Iter prev = beg;
+ for (++beg; beg != end; ++beg, ++prev)
+ {
+ if (!comp(*prev, *beg))
+ return false;
+ }
+ return true;
+}
+
+template <typename Iter, typename Compare>
+Iter RemoveIfKeepValid(Iter beg, Iter end, Compare comp)
+{
+ while (beg != end)
+ {
+ if (comp(*beg))
+ {
+ while (beg != --end)
+ {
+ if (!comp(*end))
+ {
+ std::swap(*beg, *end);
+ ++beg;
+ break;
+ }
+ }
+ }
+ else
+ ++beg;
+ }
+
+ return end;
+}
+
+template <typename Iter>
+bool IsSortedAndUnique(Iter beg, Iter end)
+{
+ return IsSortedAndUnique(beg, end, std::less<typename std::iterator_traits<Iter>::value_type>());
+}
+
+struct DeleteFunctor
+{
+ template <typename T>
+ void operator()(T const * p) const
+ {
+ delete p;
+ }
+};
+
+template <typename Container, typename Deletor>
+impl::DeleteRangeFunctor<Container, Deletor> GetRangeDeletor(Container & cont,
+ Deletor const & deletor)
+{
+ return impl::DeleteRangeFunctor<Container, Deletor>(cont, deletor);
+}
+
+template <typename Container, typename Deletor>
+void DeleteRange(Container & cont, Deletor const & deletor)
+{
+ (void)GetRangeDeletor(cont, deletor)();
+}
+
+struct IdFunctor
+{
+ template <typename T>
+ T operator()(T const & x) const
+ {
+ return x;
+ }
+};
+
+template <typename T>
+struct EqualFunctor
+{
+ T const & m_t;
+ explicit EqualFunctor(T const & t) : m_t(t) {}
+ bool operator()(T const & t) const { return (t == m_t); }
+};
+
+template <typename Iter>
+Iter NextIterInCycle(Iter it, Iter beg, Iter end)
+{
+ if (++it == end)
+ return beg;
+ return it;
+}
+
+template <typename Iter>
+Iter PrevIterInCycle(Iter it, Iter beg, Iter end)
+{
+ if (it == beg)
+ it = end;
+ return --it;
+}
+
+template <typename Iter1, typename Iter2, typename InsertIter>
+void AccumulateIntervals1With2(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, InsertIter res)
+{
+ using T = typename std::iterator_traits<Iter1>::value_type;
+
+ T prev;
+ bool validPrev = false;
+
+ while (b1 != e1 || b2 != e2)
+ {
+ // Try to continue previous range.
+ if (validPrev)
+ {
+ // add b1 range to prev if needed
+ if (b1 != e1 && b1->first < prev.second)
+ {
+ // correct only second if needed
+ if (prev.second < b1->second)
+ prev.second = b1->second;
+ ++b1;
+ continue;
+ }
+
+ // add b2 range to prev if needed
+ if (b2 != e2 && b2->first < prev.second)
+ {
+ // check that intervals are overlapped
+ if (prev.first < b2->second)
+ {
+ // correct first and second if needed
+ if (b2->first < prev.first)
+ prev.first = b2->first;
+ if (prev.second < b2->second)
+ prev.second = b2->second;
+ }
+
+ ++b2;
+ continue;
+ }
+
+ // if nothing to add - push to results
+ *res++ = prev;
+ validPrev = false;
+ }
+
+ if (b1 != e1)
+ {
+ // start new range
+ prev = *b1++;
+ validPrev = true;
+ }
+ else
+ {
+ // go to exit
+ break;
+ }
+ }
+
+ if (validPrev)
+ *res++ = prev;
+}
+} // namespace base
diff --git a/base/string_utils.hpp b/base/string_utils.hpp
index 3fe0807500..778818b018 100644
--- a/base/string_utils.hpp
+++ b/base/string_utils.hpp
@@ -2,7 +2,7 @@
#include "base/buffer_vector.hpp"
#include "base/macros.hpp"
-#include "base/stl_add.hpp"
+#include "base/stl_helpers.hpp"
#include <algorithm>
#include <cstdint>
@@ -317,7 +317,7 @@ template <template <typename ...> class Collection = std::vector>
Collection<std::string> Tokenize(std::string const & str, char const * delims)
{
Collection<std::string> c;
- Tokenize(str, delims, MakeInsertFunctor(c));
+ Tokenize(str, delims, base::MakeInsertFunctor(c));
return c;
}