Vcsn  2.2
Be Rational
algorithm.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 #include <iterator> // next
5 
6 #include <boost/range/algorithm/set_algorithm.hpp>
7 #include <boost/range/iterator_range_core.hpp>
8 
9 namespace vcsn
10 {
11  namespace detail
12  {
13  // Not in Boost 1.49.
14  template <typename Range, typename Predicate>
15  bool any_of(const Range &r, Predicate p)
16  {
17  using std::begin;
18  using std::end;
19  return std::any_of(begin(r), end(r), p);
20  }
21 
25  template <typename Container>
26  typename Container::value_type
27  back(const Container& container)
28  {
29  using std::begin;
30  using std::end;
31  auto i = begin(container);
32  auto iend = end(container);
33  assert(i != iend);
34  auto res = *i;
35  for (++i; i != iend; ++i)
36  res = *i;
37  return res;
38  }
39 
40  template <typename Container, typename Predicate>
41  void erase_if(Container& c, const Predicate& p)
42  {
43  using std::begin;
44  using std::end;
45  for (auto i = begin(c); i != end(c); /* nothing. */)
46  {
47  if (p(*i))
48  i = c.erase(i);
49  else
50  ++i;
51  }
52  }
53 
54 
56  template <typename Container>
57  typename Container::value_type
58  front(const Container& container)
59  {
60  using std::begin;
61  using std::end;
62  auto i = begin(container);
63  assert(i != end(container));
64  return *i;
65  }
66 
69  template <typename Iterator, typename Pred, typename Less>
70  boost::iterator_range<Iterator>
71  initial_sorted_range(Iterator begin, Iterator end,
72  Pred pred, Less less)
73  {
74  if (pred(*begin))
75  for (auto i = begin;; ++i)
76  {
77  auto next = std::next(i);
78  if (next == end
79  || !pred(*next)
80  || less(*next, *i))
81  return {begin, next};
82  }
83  else
84  return {end, end};
85  }
86 
91  template <typename Container, typename Compare>
92  bool is_sorted_forward(const Container& container, Compare comp)
93  {
94  auto i = std::begin(container);
95  auto end = std::end(container);
96  if (i != end)
97  {
98  auto prev = *i;
99  for (++i; i != end; ++i)
100  if (comp(prev, *i))
101  prev = *i;
102  else
103  return false;
104  }
105  return true;
106  }
107 
110  template <typename Container>
111  typename Container::value_type
112  max_forward(const Container& container)
113  {
114  auto i = std::begin(container);
115  auto end = std::end(container);
116  assert(i != end);
117  if (i != end)
118  {
119  auto res = *i;
120  for (++i; i != end; ++i)
121  if (res < *i)
122  res = *i;
123  return res;
124  }
125  abort();
126  }
127 
128  // Boost 1.49 does not have boost/algorithm/cxx11/none_of.hpp and the like.
129  template <typename Range, typename Predicate>
130  bool none_of(const Range &r, Predicate p)
131  {
132  using std::begin;
133  using std::end;
134  return std::none_of(begin(r), end(r), p);
135  }
136 
137  // Not in Boost 1.49.
138  template <typename Range, typename Value>
139  bool none_of_equal(const Range &r, const Value& value)
140  {
141  return none_of(r, [&value](const Value& v) { return v == value; });
142  }
143  }
144 
146  template <typename Container,
147  // SFINAE.
148  typename = typename Container::value_type>
149  Container
150  set_difference(const Container& s1, const Container& s2)
151  {
152  auto res = Container{s1.key_comp(), s1.get_allocator()};
153  auto i = std::insert_iterator<Container>{res, res.begin()};
154  boost::set_difference(s1, s2, i, s1.key_comp());
155  return res;
156  }
157 
159  template <typename Container,
160  // SFINAE.
161  typename = typename Container::value_type>
162  Container
163  set_intersection(const Container& s1, const Container& s2)
164  {
165  auto res = Container{s1.key_comp(), s1.get_allocator()};
166  auto i = std::insert_iterator<Container>{res, res.begin()};
167  boost::set_intersection(s1, s2, i, s1.key_comp());
168  return res;
169  }
170 
172  template <typename Container>
173  bool
174  same_domain(const Container& x, const Container& y)
175  {
176  if (x.size() == y.size())
177  {
178  using std::begin; using std::end;
179  for (auto xi = begin(x), xend = end(x), yi = begin(y);
180  xi != xend;
181  ++xi, ++yi)
182  if (x.key_comp()(xi->first, yi->first)
183  || x.key_comp()(yi->first, xi->first))
184  return false;
185  return true;
186  }
187  else
188  return false;
189  }
190 
192  template <typename Container,
193  // SFINAE.
194  typename = typename Container::value_type>
195  Container
196  set_union(const Container& s1, const Container& s2)
197  {
198  auto res = Container{s1.key_comp(), s1.get_allocator()};
199  auto i = std::insert_iterator<Container>{res, res.begin()};
200  boost::set_union(s1, s2, i, s1.key_comp());
201  return res;
202  }
203 }
boost::iterator_range< Iterator > initial_sorted_range(Iterator begin, Iterator end, Pred pred, Less less)
The return the longest initial range of elements matching the predicate.
Definition: algorithm.hh:71
Container::value_type back(const Container &container)
The last member of this Container.
Definition: algorithm.hh:27
bool any_of(const Range &r, Predicate p)
Definition: algorithm.hh:15
bool is_sorted_forward(const Container &container, Compare comp)
Same as std::is_sorted, but works with an input iterator, not just a forward iterator.
Definition: algorithm.hh:92
Definition: a-star.hh:8
bool same_domain(const Container &x, const Container &y)
Check that two associative containers have the same keys.
Definition: algorithm.hh:174
Container::value_type max_forward(const Container &container)
Same as *std::max_element, but works with an input iterator, not just a forward iterator.
Definition: algorithm.hh:112
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
bool none_of(const Range &r, Predicate p)
Definition: algorithm.hh:130
void erase_if(Container &c, const Predicate &p)
Definition: algorithm.hh:41
Container set_union(const Container &s1, const Container &s2)
The union of two sets.
Definition: algorithm.hh:196
bool none_of_equal(const Range &r, const Value &value)
Definition: algorithm.hh:139
Container set_intersection(const Container &s1, const Container &s2)
The intersection of two sets.
Definition: algorithm.hh:163
Container::value_type front(const Container &container)
The first member of this Container.
Definition: algorithm.hh:58
Container set_difference(const Container &s1, const Container &s2)
The set of members of s1 that are not members of s2.
Definition: algorithm.hh:150
Functor to compare Values of ValueSets.
Definition: functional.hh:78