Skip to content

Commit 4790fe5

Browse files
committed
[WIP] upgrade to C++20 features (concepts, etc.)
1 parent a7dda2d commit 4790fe5

File tree

11 files changed

+151
-196
lines changed

11 files changed

+151
-196
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
build
1+
build*

.vscode/settings.json

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,76 @@
33
"*.scons": "python",
44
"regex": "cpp",
55
"xutility": "cpp",
6-
"optional": "cpp"
6+
"optional": "cpp",
7+
"iosfwd": "cpp",
8+
"type_traits": "cpp",
9+
"functional": "cpp",
10+
"algorithm": "cpp",
11+
"complex": "cpp",
12+
"system_error": "cpp",
13+
"xlocmon": "cpp",
14+
"xtr1common": "cpp",
15+
"array": "cpp",
16+
"atomic": "cpp",
17+
"bit": "cpp",
18+
"cctype": "cpp",
19+
"charconv": "cpp",
20+
"clocale": "cpp",
21+
"cmath": "cpp",
22+
"compare": "cpp",
23+
"concepts": "cpp",
24+
"cstddef": "cpp",
25+
"cstdint": "cpp",
26+
"cstdio": "cpp",
27+
"cstdlib": "cpp",
28+
"cstring": "cpp",
29+
"ctime": "cpp",
30+
"cwchar": "cpp",
31+
"deque": "cpp",
32+
"exception": "cpp",
33+
"format": "cpp",
34+
"forward_list": "cpp",
35+
"initializer_list": "cpp",
36+
"ios": "cpp",
37+
"iostream": "cpp",
38+
"istream": "cpp",
39+
"iterator": "cpp",
40+
"limits": "cpp",
41+
"list": "cpp",
42+
"locale": "cpp",
43+
"memory": "cpp",
44+
"mutex": "cpp",
45+
"new": "cpp",
46+
"ostream": "cpp",
47+
"queue": "cpp",
48+
"ranges": "cpp",
49+
"ratio": "cpp",
50+
"set": "cpp",
51+
"span": "cpp",
52+
"sstream": "cpp",
53+
"stdexcept": "cpp",
54+
"stop_token": "cpp",
55+
"streambuf": "cpp",
56+
"string": "cpp",
57+
"thread": "cpp",
58+
"tuple": "cpp",
59+
"typeinfo": "cpp",
60+
"unordered_map": "cpp",
61+
"unordered_set": "cpp",
62+
"utility": "cpp",
63+
"valarray": "cpp",
64+
"vector": "cpp",
65+
"xfacet": "cpp",
66+
"xhash": "cpp",
67+
"xiosbase": "cpp",
68+
"xlocale": "cpp",
69+
"xlocbuf": "cpp",
70+
"xlocinfo": "cpp",
71+
"xlocmes": "cpp",
72+
"xlocnum": "cpp",
73+
"xloctime": "cpp",
74+
"xmemory": "cpp",
75+
"xstring": "cpp",
76+
"xtree": "cpp"
777
}
878
}

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ target_precompile_headers(c++spec INTERFACE
1818
${c++spec_headers}
1919
)
2020

21-
option(BUILD_TESTS "Build tests." OFF)
21+
option(BUILD_TESTS "Build tests." ON)
2222

2323
if(BUILD_TESTS)
2424
# enable_testing()
@@ -27,7 +27,7 @@ if(BUILD_TESTS)
2727
add_subdirectory(spec)
2828
endif(BUILD_TESTS)
2929

30-
option(BUILD_EXAMPLES "Build examples." OFF)
30+
option(BUILD_EXAMPLES "Build examples." ON)
3131

3232
if(BUILD_EXAMPLES)
3333
add_subdirectory(examples)

include/expectations/expectation.hpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -480,10 +480,8 @@ class ExpectationValue : public Expectation<A> {
480480
}
481481
};
482482

483-
template <typename F>
483+
template <Util::is_functional F>
484484
class ExpectationFunc : public Expectation<decltype(std::declval<F>()())> {
485-
static_assert(Util::is_functional<F>::value,
486-
"Error! ExpectationFunc can only contaion lambdas.");
487485

488486
typedef decltype(std::declval<F>()()) block_ret_t;
489487
F block;
@@ -549,7 +547,7 @@ class ExpectationFunc : public Expectation<decltype(std::declval<F>()())> {
549547
Result to_throw(std::string msg = "");
550548
};
551549

552-
template <typename F>
550+
template <Util::is_functional F>
553551
template <typename Ex>
554552
Result ExpectationFunc<F>::to_throw(std::string msg) {
555553
Matchers::Throw<decltype(this->block.operator()()), Ex> matcher(*this);

include/it.hpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <string>
77
#include <vector>
8+
89
#include "expectations/expectation.hpp"
910

1011
namespace CppSpec {
@@ -123,17 +124,13 @@ class ItCD : public ItBase {
123124
* expect([] -> int { return 4; })
124125
* @endcode
125126
*/
126-
template <class T>
127-
typename std::enable_if<not Util::is_functional<T>::value,
128-
ExpectationValue<T>>::type
129-
ItBase::expect(T value) {
127+
template <Util::is_not_functional T>
128+
ExpectationValue<T> ItBase::expect(T value) {
130129
return ExpectationValue<T>(*this, value);
131130
}
132131

133-
template <typename T>
134-
auto ItBase::expect(T block) ->
135-
typename std::enable_if<Util::is_functional<T>::value,
136-
ExpectationFunc<T>>::type {
132+
template <Util::is_functional T>
133+
ExpectationFunc<T> ItBase::expect(T block) {
137134
return ExpectationFunc<T>(*this, block);
138135
}
139136

@@ -149,7 +146,7 @@ ExpectationValue<T> ItBase::expect(Let<T> &let) {
149146
* expect({1,2,3})
150147
* @endcode
151148
*/
152-
template <class T>
149+
template <typename T>
153150
ExpectationValue<std::initializer_list<T>> ItBase::expect(
154151
std::initializer_list<T> init_list) {
155152
return ExpectationValue<std::initializer_list<T>>(*this, init_list);

include/it_base.hpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@
55

66
#include <string>
77
#include <vector>
8-
#include "runnable.hpp"
8+
99
#include "let.hpp"
10+
#include "runnable.hpp"
1011
#include "util.hpp"
1112

1213
namespace CppSpec {
1314

1415
template <typename T>
1516
class ExpectationValue;
16-
template <typename T>
17+
template <Util::is_functional T>
1718
class ExpectationFunc;
1819

1920
/**
@@ -34,8 +35,8 @@ class ItBase : public Runnable {
3435
ItBase() = delete; // Don't allow a default constructor
3536

3637
/** @brief Copy constructor */
37-
ItBase(const ItBase &copy) noexcept : Runnable(copy),
38-
description(copy.description) {}
38+
ItBase(const ItBase &copy) noexcept
39+
: Runnable(copy), description(copy.description) {}
3940

4041
/**
4142
* @brief Create an BaseIt without an explicit description
@@ -49,8 +50,7 @@ class ItBase : public Runnable {
4950
* @return the constructed BaseIt
5051
*/
5152
explicit ItBase(const Child &parent, std::string description) noexcept
52-
: Runnable(parent),
53-
description(description) {}
53+
: Runnable(parent), description(description) {}
5454

5555
/**
5656
* @brief Get whether the object needs a description string
@@ -85,10 +85,8 @@ class ItBase : public Runnable {
8585
*
8686
* @return a ExpectationValue object containing the given value.
8787
*/
88-
template <typename T>
89-
typename std::enable_if<not Util::is_functional<T>::value,
90-
ExpectationValue<T>>::type
91-
expect(T value);
88+
template <Util::is_not_functional T>
89+
ExpectationValue<T> expect(T value);
9290

9391
/**
9492
* @brief The `expect` object generator for lambdas
@@ -99,10 +97,8 @@ class ItBase : public Runnable {
9997
*
10098
* @return a ExpectationFunc object containing the given value.
10199
*/
102-
template <typename T>
103-
typename std::enable_if<Util::is_functional<T>::value,
104-
ExpectationFunc<T>>::type
105-
expect(T block);
100+
template <Util::is_functional T>
101+
ExpectationFunc<T> expect(T block);
106102

107103
/**
108104
* @brief The `expect` object generator for initializer lists

include/matchers/contain.hpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ class ContainBase : public MatcherBase<A, E> {
2020
virtual std::string failure_message_when_negated() override;
2121
virtual bool diffable() { return true; }
2222

23-
protected:
24-
bool actual_collection_includes(U expected_item);
25-
ContainBase(Expectation<A> &expectation,
26-
std::initializer_list<U> expected)
23+
ContainBase(Expectation<A> &expectation, std::initializer_list<U> expected)
2724
: MatcherBase<A, std::vector<U>>(expectation, std::vector<U>(expected)),
2825
actual(this->get_actual()){};
2926
ContainBase(Expectation<A> &expectation, U expected)
3027
: MatcherBase<A, U>(expectation, expected), actual(this->get_actual()){};
28+
29+
protected:
30+
bool actual_collection_includes(U expected_item);
3131
};
3232

3333
template <typename A, typename E, typename U>
@@ -53,7 +53,7 @@ bool ContainBase<A, E, U>::actual_collection_includes(U expected_item) {
5353
auto actual = this->get_actual();
5454
auto last = *(actual.begin());
5555
static_assert(
56-
Util::verbose_assert<std::is_same<decltype(last), U>>::value,
56+
Util::verbose_assert<std::is_same_v<decltype(last), U>>::value,
5757
"Expected item is not the same type as what is inside container.");
5858
return std::find(actual.begin(), actual.end(), expected_item) != actual.end();
5959
}
@@ -69,9 +69,7 @@ class Contain : public ContainBase<A, E, U> {
6969
public:
7070
bool match() override;
7171
bool negated_match() override;
72-
Contain(Expectation<A> &expectation,
73-
std::initializer_list<U> expected)
74-
: ContainBase<A, E, U>(expectation, expected){};
72+
using ContainBase<A, E, U>::ContainBase;
7573

7674
protected:
7775
bool perform_match(Predicate predicate, Predicate hash_subset_predicate);
@@ -138,6 +136,6 @@ bool Contain<A, U, U>::match() {
138136
return this->actual_collection_includes(this->get_expected());
139137
}
140138

141-
} // ::Matchers
139+
} // namespace Matchers
142140
} // namespace CppSpec
143141
#endif // CPPSPEC_MATCHERS_INCLUDE_HPP

include/matchers/end_with.hpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,14 @@
44
#pragma once
55

66
#include <string>
7+
#include <ranges>
78
#include "matcher_base.hpp"
89

910
namespace CppSpec {
1011
namespace Matchers {
1112

12-
template <typename A, typename E>
13+
template <std::ranges::range A, std::ranges::range E>
1314
class EndWith : public MatcherBase<A, E> {
14-
static_assert(Util::is_iterable<A>::value && Util::is_iterable<E>::value,
15-
"Error! Trying to match starting items with a non-iterable "
16-
"container");
17-
1815
public:
1916
EndWith(Expectation <A> &expectation, E start)
2017
: MatcherBase<A, E>(expectation, start) { }

include/matchers/pretty_matchers.hpp

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,11 @@ struct Pretty {
3333
static std::string last(const std::string &s, const char delim);
3434
static std::string improve_hash_formatting(std::string inspect_string);
3535

36-
template <typename T>
37-
static
38-
typename std::enable_if<Util::is_streamable<T>::value, std::string>::type
39-
to_word(T &item);
36+
template <Util::is_streamable T>
37+
static std::string to_word(T &item);
4038

4139
template <typename T>
42-
static
43-
typename std::enable_if<!Util::is_streamable<T>::value, std::string>::type
44-
to_word(T &item);
40+
static std::string to_word(T &item);
4541

4642
template <typename T>
4743
static std::string to_word_type(T &item);
@@ -120,9 +116,8 @@ inline std::string Pretty::to_sentance(T &item) {
120116
*
121117
* @return the string representation
122118
*/
123-
template <typename T>
124-
typename std::enable_if<Util::is_streamable<T>::value,
125-
std::string>::type inline Pretty::to_word(T &item) {
119+
template <Util::is_streamable T>
120+
inline std::string Pretty::to_word(T &item) {
126121
std::stringstream ss;
127122
ss << item;
128123
return ss.str();
@@ -151,8 +146,7 @@ inline std::string Pretty::to_word<std::false_type>(std::false_type &item) {
151146
* @return the string representation
152147
*/
153148
template <typename T>
154-
typename std::enable_if<!Util::is_streamable<T>::value,
155-
std::string>::type inline Pretty::to_word(T &item) {
149+
inline std::string Pretty::to_word(T &item) {
156150
std::stringstream ss;
157151
// Ruby-style inspect for objects without an overloaded operator<<
158152
ss << "#<" << Util::demangle(typeid(item).name()) << ":" << &item << ">";
@@ -183,7 +177,7 @@ inline std::string Pretty::to_word(Matchers::MatcherBase<A, E> &matcher) {
183177
template <typename T>
184178
inline std::string Pretty::to_word_type(T &item) {
185179
std::string word = to_word(item);
186-
if (Util::is_streamable<T>::value) {
180+
if constexpr (Util::is_streamable<T>) {
187181
word += " : " + Util::demangle(typeid(T).name());
188182
}
189183
return word;

include/matchers/start_with.hpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,14 @@
44
#pragma once
55

66
#include <string>
7+
#include <ranges>
78
#include "matcher_base.hpp"
89

910
namespace CppSpec {
1011
namespace Matchers {
1112

12-
template <typename A, typename E>
13+
template <std::ranges::range A, std::ranges::range E>
1314
class StartWith : public MatcherBase<A, E> {
14-
static_assert(Util::is_iterable<A>::value && Util::is_iterable<E>::value,
15-
"Error! Trying to match starting items with a non-iterable "
16-
"container");
1715

1816
public:
1917
StartWith(Expectation <A> &expectation, E start)

0 commit comments

Comments
 (0)