Skip to content

Commit e8a2ca8

Browse files
committed
Add boost algorithms replacement
1 parent 2bc48d7 commit e8a2ca8

File tree

2 files changed

+155
-0
lines changed

2 files changed

+155
-0
lines changed

src/detail/algorithm_find.hpp

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* Search algorithms
3+
* @author Lobaskin Vasily
4+
* @data 31 March 2020
5+
* @copyright Boost Software License, Version 1.0
6+
*/
7+
8+
#pragma once
9+
10+
#include <cstddef>
11+
12+
namespace network {
13+
namespace algorithm {
14+
15+
template <typename IteratorBegT, typename IteratorEndT, typename RangeT>
16+
IteratorBegT find_nth(IteratorBegT iteratorBeg, IteratorEndT iteratorEnd,
17+
RangeT symbol, std::size_t pos) {
18+
static_assert(std::is_same<IteratorBegT, IteratorEndT>::value,
19+
"Iterator types are different");
20+
21+
if (iteratorBeg > iteratorEnd) {
22+
std::swap(iteratorBeg, iteratorEnd);
23+
}
24+
25+
std::size_t currentPos = -1;
26+
while (iteratorBeg != iteratorEnd) {
27+
if (*iteratorBeg == symbol) {
28+
++currentPos;
29+
if (currentPos == pos) break;
30+
}
31+
++iteratorBeg;
32+
}
33+
34+
return iteratorBeg;
35+
}
36+
37+
template <typename IteratorBegT, typename IteratorEndT, typename ConditionT>
38+
bool all(IteratorBegT iteratorBeg, IteratorEndT iteratorEnd,
39+
ConditionT &&condition) {
40+
static_assert(std::is_same<IteratorBegT, IteratorEndT>::value,
41+
"Iterator types are different");
42+
43+
if (iteratorBeg > iteratorEnd) {
44+
std::swap(iteratorBeg, iteratorEnd);
45+
}
46+
47+
while (iteratorBeg != iteratorEnd) {
48+
if (!condition(*iteratorBeg)) return false;
49+
50+
++iteratorBeg;
51+
}
52+
53+
return true;
54+
}
55+
56+
template <typename ContainerT, typename RangeT>
57+
typename ContainerT::const_iterator find_nth(ContainerT const &str,
58+
RangeT symbol, std::size_t pos) {
59+
return algorithm::find_nth(str.begin(), str.end(), symbol, pos);
60+
}
61+
62+
template <typename ContainerT, typename RangeT>
63+
typename ContainerT::const_iterator find_last(ContainerT const &str,
64+
RangeT symbol) {
65+
auto iter = algorithm::find_nth(str.rbegin(), str.rend(), symbol, 0);
66+
if (iter == str.rend()) {
67+
return str.end();
68+
}
69+
70+
return (++iter).base();
71+
}
72+
73+
template <typename ContainerT, typename ConditionT>
74+
bool all(ContainerT const &container, ConditionT &&condition) {
75+
return all(container.cbegin(), container.cend(),
76+
std::forward<ConditionT>(condition));
77+
}
78+
79+
} // namespace algorithm
80+
} // namespace network

src/detail/algorithm_split.hpp

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/**
2+
* Search algorithms
3+
* @author Lobaskin Vasily
4+
* @data 31 March 2020
5+
* @copyright Boost Software License, Version 1.0
6+
*/
7+
8+
#include <type_traits>
9+
10+
namespace network {
11+
namespace algorithm {
12+
13+
template <typename ContainerT, class SequenceT, typename SplitterT,
14+
typename std::enable_if<std::is_fundamental<SplitterT>::value>::type
15+
* = nullptr>
16+
bool split(ContainerT &container, SequenceT const &str, SplitterT symbol) {
17+
using PartT = typename ContainerT::value_type;
18+
static_assert(std::is_same<typename SequenceT::value_type, SplitterT>::value,
19+
"Splitter type doesn't match sequence inner type");
20+
21+
std::size_t sequenceStart = 0;
22+
for (std::size_t i = 0, len = str.size(); i <= len; ++i) {
23+
if (str[i] != symbol && i != len) continue;
24+
25+
std::size_t substrLen = i - sequenceStart;
26+
if (substrLen > 0) {
27+
PartT part{str.cbegin() + sequenceStart, str.cbegin() + i};
28+
container.emplace_back(std::move(part));
29+
} else {
30+
container.emplace_back(PartT{});
31+
}
32+
sequenceStart = i + 1;
33+
}
34+
35+
return true;
36+
}
37+
38+
template <typename ContainerT, class SequenceT, typename SplitterT,
39+
typename std::enable_if<!std::is_fundamental<SplitterT>::value>::type
40+
* = nullptr>
41+
bool split(ContainerT &container, SequenceT const &str, SplitterT splitter) {
42+
using PartT = typename ContainerT::value_type;
43+
static_assert(
44+
std::is_same<typename ContainerT::value_type, std::string>::value,
45+
"Invalid container type, only string is supported");
46+
47+
bool isEqual = false;
48+
std::size_t sequenceLen = splitter.size();
49+
std::size_t sequenceStart = 0;
50+
for (std::size_t i = 0, len = str.size(); i <= len; ++i) {
51+
isEqual = true;
52+
for (std::size_t j = 0; j < sequenceLen; ++j) {
53+
if (str[i + j] != splitter[j]) {
54+
isEqual = false;
55+
break;
56+
}
57+
}
58+
if (!isEqual && i != len) continue;
59+
60+
std::size_t substrLen = i - sequenceStart;
61+
if (substrLen > 0) {
62+
PartT part{str.cbegin() + sequenceStart, str.cbegin() + i};
63+
container.emplace_back(std::move(part));
64+
} else {
65+
container.emplace_back(PartT{});
66+
}
67+
sequenceStart = i + sequenceLen;
68+
i += sequenceLen - 1;
69+
}
70+
71+
return true;
72+
}
73+
74+
} // namespace algorithm
75+
} // namespace network

0 commit comments

Comments
 (0)