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

stl_helpers.hpp « base - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 2130dd03d7c7a716c0e315becf56fc7f6f99ac5c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#pragma once

#include <algorithm>
#include <functional>
#include <utility>
#include <vector>

namespace my
{
namespace impl
{
// When isField is true, following functors operate on a
// pointers-to-field.  Otherwise, they operate on a
// pointers-to-const-method.
template <bool isField, typename T, typename C>
struct Less;

template <typename T, typename C>
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; }

  inline bool operator()(C const * const lhs, C const * const rhs) const
  {
    return lhs->*m_p < rhs->*m_p;
  }

  T(C::*m_p);
};

template <typename T, typename C>
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)(); }

  inline bool operator()(C const * const lhs, C const * const rhs) const
  {
    return (lhs->*m_p)() < (rhs->*m_p)();
  }

  T (C::*m_p)() const;
};

template <bool isField, typename T, typename C>
struct Equals;

template <typename T, typename C>
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; }

  inline bool operator()(C const * const lhs, C const * const rhs) const
  {
    return lhs->*m_p == rhs->*m_p;
  }

  T(C::*m_p);
};

template <typename T, typename C>
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)(); }

  inline bool operator()(C const * const lhs, C const * const rhs) const
  {
    return (lhs->*m_p)() == (rhs->*m_p)();
  }

  T (C::*m_p)() const;
};
}  // namespace impl

// Sorts and removes duplicate entries from |c|.
template <typename Cont>
void SortUnique(Cont & c)
{
  sort(c.begin(), c.end());
  c.erase(unique(c.begin(), c.end()), c.end());
}

// 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(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>
void EraseIf(Cont & c, Fn && fn)
{
  c.erase(remove_if(c.begin(), c.end(), std::forward<Fn>(fn)), c.end());
}

// Creates a comparer being able to compare two instances of class C
// (given by reference or pointer) by a field or const method of C.
// For example, to create comparer that is able to compare pairs of
// ints by second component, it's enough to call LessBy(&pair<int,
// int>::second).
template <typename T, typename C>
impl::Less<true, T, C> LessBy(T(C::*p))
{
  return impl::Less<true, T, C>(p);
}

template <typename T, typename C>
impl::Less<false, T, C> LessBy(T (C::*p)() const)
{
  return impl::Less<false, T, C>(p);
}

template <typename T, typename C>
impl::Equals<true, T, C> EqualsBy(T(C::*p))
{
  return impl::Equals<true, T, C>(p);
}

template <typename T, typename C>
impl::Equals<false, T, C> EqualsBy(T (C::*p)() const)
{
  return impl::Equals<false, T, C>(p);
}

template <typename T>
typename std::underlying_type<T>::type Key(T value)
{
  return static_cast<typename std::underlying_type<T>::type>(value);
}
}  // namespace my