summaryrefslogtreecommitdiff
path: root/graphics/asymptote/LspCpp/third_party/uri/src/detail/algorithm_find.hpp
blob: 4d8b99602bfc90204f384c86832ceafeebbc396e (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
/**
 * Search algorithms
 * @author Lobaskin Vasily
 * @data 31 March 2020
 * @copyright Boost Software License, Version 1.0
 */

#pragma once

#include <cstddef>

namespace network {
namespace algorithm {

template <typename IteratorBegT, typename IteratorEndT, typename RangeT>
IteratorBegT find_nth(IteratorBegT iteratorBeg, IteratorEndT iteratorEnd,
                      RangeT symbol, std::size_t pos) {
  static_assert(std::is_same<IteratorBegT, IteratorEndT>::value,
                "Iterator types are different");

  if (iteratorBeg > iteratorEnd) {
    std::swap(iteratorBeg, iteratorEnd);
  }

  std::size_t currentPos = -1;
  while (iteratorBeg != iteratorEnd) {
    if (*iteratorBeg == symbol) {
      ++currentPos;
      if (currentPos == pos) break;
    }
    ++iteratorBeg;
  }

  return iteratorBeg;
}

template <typename IteratorBegT, typename IteratorEndT, typename ConditionT>
bool all(IteratorBegT iteratorBeg, IteratorEndT iteratorEnd,
         ConditionT &&condition) {
  static_assert(std::is_same<IteratorBegT, IteratorEndT>::value,
                "Iterator types are different");

  if (iteratorBeg > iteratorEnd) {
    std::swap(iteratorBeg, iteratorEnd);
  }

  while (iteratorBeg != iteratorEnd) {
    if (!condition(*iteratorBeg)) return false;

    ++iteratorBeg;
  }

  return true;
}

template <typename ContainerT, typename RangeT>
typename ContainerT::iterator find_nth(ContainerT &str, RangeT symbol,
                                       std::size_t pos) {
  return algorithm::find_nth(str.begin(), str.end(), symbol, pos);
}

template <typename ContainerT, typename RangeT>
typename ContainerT::iterator find_last(ContainerT &str, RangeT symbol) {
  auto iter = algorithm::find_nth(str.rbegin(), str.rend(), symbol, 0);
  if (iter == str.rend()) {
    return str.end();
  }

  return (++iter).base();
}

template <typename ContainerT, typename ConditionT>
bool all(ContainerT const &container, ConditionT &&condition) {
  return all(container.cbegin(), container.cend(),
             std::forward<ConditionT>(condition));
}

}  // namespace algorithm
}  // namespace network