-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.hpp
151 lines (121 loc) · 4.78 KB
/
utils.hpp
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
141
142
143
144
145
146
147
148
149
150
151
#pragma once
#include "traits.hpp"
namespace ft {
template <class T>
struct switch_const {
typedef T type;
};
template <class T>
struct switch_const<const T> {
typedef T type;
};
template <class Arg1, class Arg2, class Result>
struct binary_function {
typedef Arg1 first_argument_type;
typedef Arg2 second_argument_type;
typedef Result result_type;
};
template <class T>
struct less : binary_function <T, T, bool> {
bool operator()(const T& x, const T& y) const {
return x < y;
}
};
// Creates an integer constant from type and value.
template <class T, bool val>
struct integral_constant {
static const bool value = val; // refers not to an instance but to the class itself, don't need to create an instance to refer to the parameter, const is at compile time and cannot be changed
typedef T value_type;
typedef integral_constant type;
operator value_type() const {
return value;
}
};
// An instance of a type predicate has the value true if type T is a form of one of the integer types, otherwise it has the value false.
template <class T>
struct is_integral : public ft::integral_constant<T, false> {};
template <>
struct is_integral<bool> : public ft::integral_constant<bool, true> {};
template <>
struct is_integral<char> : public ft::integral_constant<bool, true> {};
template <>
struct is_integral<signed char> : public ft::integral_constant<bool, true> {};
template <>
struct is_integral<unsigned char> : public ft::integral_constant<bool, true> {};
template <>
struct is_integral<wchar_t> : public ft::integral_constant<bool, true> {};
template <>
struct is_integral<char16_t> : public ft::integral_constant<bool, true> {};
template <>
struct is_integral<short> : public ft::integral_constant<bool, true> {};
template <>
struct is_integral<unsigned short> : public ft::integral_constant<bool, true> {};
template <>
struct is_integral<int> : public ft::integral_constant<bool, true> {};
template <>
struct is_integral<unsigned int> : public ft::integral_constant<bool, true> {};
template <>
struct is_integral<long> : public ft::integral_constant<bool, true> {};
template <>
struct is_integral<unsigned long> : public ft::integral_constant<bool, true> {};
template <>
struct is_integral<long long> : public ft::integral_constant<bool, true> {};
template <>
struct is_integral<unsigned long long> : public ft::integral_constant<bool, true> {};
// "Metaprogramming" - compile-time programming
// SFINAE — substitution failure is not an error
template <bool Condition, class T = void> // compile time error is not an error
struct enable_if {};
// Specialisation enable_if
template <class T>
struct enable_if<true, T> {
typedef T type;
};
// Compares corresponding pairs of elements from two sequences bounded by ranges [first1, last1] and [first2, last2]. The comparison continues until the first pair of different elements is found, the pair [last1,last2] is reached, or at least one of the elements last1 or last2 (if the sequences have different lengths).
template <class InputIt1, class InputIt2>
bool lexicographical_compare(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2) {
for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
if (*first1 < *first2)
return true;
if (*first2 < *first1)
return false;
}
return (first1 == last1) && (first2 != last2);
}
template <class InputIt1, class InputIt2, class Compare>
bool lexicographical_compare(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Compare comp) {
for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
if (comp(*first1 < *first2))
return true;
if (comp(*first2 < *first1))
return false;
}
return (first1 == last1) && (first2 != last2);
}
template <class InputIt1, class InputIt2>
bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2) {
for(; first1 != last1; ++first1, ++first2) {
if(!(*first1 == *first2)) {
return false;
}
}
return true;
}
template <class InputIt1, class InputIt2, class BinaryPredicate>
bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, BinaryPredicate predicate) {
for(; first1 != last1; ++first1, ++first2) {
if(!predicate(*first1, *first2)) {
return false;
}
}
return true;
}
// Distance between two iterators in size_type value.
template <class InputIt1, class InputIt2>
size_t distance(InputIt1 first, InputIt2 last) {
size_t distance = 0;
for(; first != last; ++first)
distance++;
return distance;
}
}