Skip to content

Commit 61fa0ae

Browse files
committed
Begin adding constexpr and noexcept specifiers
1 parent 33946f5 commit 61fa0ae

File tree

7 files changed

+109
-89
lines changed

7 files changed

+109
-89
lines changed

include/child.hpp

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33
#define CPPSPEC_CHILD_HPP
44
#pragma once
55

6+
#ifndef CPPSPEC_DEBUG
7+
#define CPPSPEC_DEBUG false
8+
#endif
9+
610
#include <string>
11+
#include <memory>
712
#include <iostream>
813
#include <typeinfo>
914

@@ -41,7 +46,6 @@ class Child {
4146
// All instances of Child start out healthy.
4247
bool status = true;
4348

44-
// TODO: Change this to a std::unique_ptr
4549
Formatters::BaseFormatter *formatter = nullptr;
4650

4751
public:
@@ -57,39 +61,55 @@ class Child {
5761
Child &operator=(const Child &) = default;
5862

5963
// Custom constructors
60-
explicit Child(Child &parent) : parent(&parent) {}
61-
explicit Child(Child *parent) : parent(parent) {}
62-
explicit Child(const Child *parent) : parent(const_cast<Child *>(parent)) {}
64+
explicit Child(Child &parent) noexcept : parent(&parent) {}
65+
explicit Child(Child *parent) noexcept : parent(parent) {}
66+
explicit Child(const Child *parent) noexcept
67+
: parent(const_cast<Child *>(parent)) {}
6368

6469
/*--------- Parent helper functions -------------*/
6570

6671
/** @brief Check to see if the Child has a parent. */
67-
const bool has_parent() { return parent != nullptr; }
72+
const bool has_parent() noexcept { return parent != nullptr; }
6873

6974
// TODO: Look in to making these references instead of pointer returns
7075
/** @brief Get the Child's parent. */
71-
Child *get_parent() { return parent; }
72-
const Child *get_parent() const { return const_cast<Child *>(parent); }
76+
constexpr Child *get_parent() noexcept { return parent; }
77+
constexpr const Child *get_parent() const noexcept {
78+
return const_cast<Child *>(parent);
79+
}
80+
7381
template <class C>
74-
C get_parent_as();
82+
constexpr C get_parent_as() noexcept {
83+
return static_cast<C>(get_parent());
84+
}
7585

7686
/** @brief Set the Child's parent */
77-
void set_parent(Child *parent) { this->parent = parent; }
87+
constexpr void set_parent(Child *parent) noexcept { this->parent = parent; }
88+
constexpr void set_parent(const Child *parent) noexcept {
89+
this->parent = const_cast<Child *>(parent);
90+
}
7891

7992
/*--------- Formatter helper functions -----------*/
80-
const bool has_formatter(); // Check to see if the tree has a printer
81-
Formatters::BaseFormatter &get_formatter(); // Get the printer from the tree
82-
void set_printer(Formatters::BaseFormatter &formatter) {
83-
this->formatter = &formatter;
93+
// Check to see if the tree has a printer
94+
constexpr const bool has_formatter() noexcept;
95+
96+
// Get the printer from the tree
97+
constexpr Formatters::BaseFormatter &get_formatter() noexcept;
98+
99+
constexpr void set_printer(const Formatters::BaseFormatter &formatter) {
100+
this->formatter = &const_cast<Formatters::BaseFormatter &>(formatter);
84101
}
85102

86103
/*--------- Primary member functions -------------*/
87104

88105
/** @brief Get the status of the object (success/failure) */
89-
const bool get_status() { return this->status; }
106+
constexpr const bool get_status() noexcept { return this->status; }
107+
constexpr const bool get_status() const noexcept { return this->status; }
108+
109+
constexpr void failed() noexcept; // Report failure to the object.
90110

91-
void failed(); // Report failure to the object.
92-
std::string padding(); // Calculate the padding for printing this object
111+
// Calculate the padding for printing this object
112+
std::string padding() noexcept;
93113
};
94114

95115
/*>>>>>>>>>>>>>>>>>>>> Child IMPLEMENTATION <<<<<<<<<<<<<<<<<<<<<<<<<*/
@@ -100,7 +120,7 @@ class Child {
100120
* This is propogated up the parent/child tree, so that when a child object
101121
* fails, the parent object is immediately updated to reflect that as well.
102122
*/
103-
inline void Child::failed() {
123+
constexpr inline void Child::failed() noexcept {
104124
this->status = false;
105125
// propogates the failure up the tree
106126
if (has_parent()) this->get_parent()->failed();
@@ -110,36 +130,19 @@ inline void Child::failed() {
110130
* @brief Generate padding (indentation) fore the current object.
111131
* @return A string of spaces for use in pretty-printing.
112132
*/
113-
inline std::string Child::padding() {
133+
inline std::string Child::padding() noexcept {
114134
return has_parent() ? get_parent()->padding() + " " : "";
115135
}
116136

117-
template <class C>
118-
inline C Child::get_parent_as() {
119-
// rejected branch should get optimized out at compile-time
120-
if (CPPSPEC_DEBUG) {
121-
if (C casted = dynamic_cast<C>(get_parent()))
122-
return casted;
123-
else
124-
throw(std::bad_cast());
125-
} else {
126-
return static_cast<C>(get_parent());
127-
}
128-
}
129-
130-
inline const bool Child::has_formatter() {
137+
constexpr inline const bool Child::has_formatter() noexcept {
131138
if (this->formatter != nullptr) return true;
132139
if (!this->has_parent()) return false; // base case;
133140
return parent->has_formatter();
134141
}
135142

136-
inline Formatters::BaseFormatter &Child::get_formatter() {
137-
if (this->formatter != nullptr) return *formatter;
138-
if (!this->has_parent()) {
139-
std::cout << "Couldn't get printer!" << std::endl;
140-
// base case. This should never *ever* happen
141-
throw "Couldn't get printer!";
142-
}
143+
constexpr inline Formatters::BaseFormatter &Child::get_formatter() noexcept {
144+
if (this->formatter) return *formatter;
145+
if (!this->has_parent()) std::terminate();
143146
return parent->get_formatter();
144147
}
145148

include/description.hpp

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ class Description : public Runnable {
2626
std::unordered_set<LetBase *> lets;
2727

2828
Description() {}
29-
explicit Description(std::string descr) : descr(descr) {}
29+
explicit Description(std::string descr) noexcept : descr(descr) {}
3030
Description(Child &parent, std::string descr, block_t body)
3131
: Runnable(parent), body(body), descr(descr) {}
3232

3333
public:
34-
3534
// Constructor
36-
Description(std::string descr, block_t body) : body(body), descr(descr) {}
35+
Description(std::string descr, block_t body) noexcept : body(body),
36+
descr(descr) {}
3737

3838
const bool has_subject = false;
3939
std::deque<rule_block_t> after_alls;
@@ -49,22 +49,13 @@ class Description : public Runnable {
4949
Result context(T subject, std::function<void(ClassDescription<T> &)> body);
5050

5151
template <class T>
52-
Result context(std::string descr, T subject, std::function<void(ClassDescription<T> &)> body);
52+
Result context(std::string descr, T subject,
53+
std::function<void(ClassDescription<T> &)> body);
5354

5455
template <class T, typename U>
5556
Result context(std::initializer_list<U> init_list,
5657
std::function<void(ClassDescription<T> &)> body);
5758

58-
// template <class T>
59-
// ClassDescription<T> subject(T subject);
60-
//
61-
// template <class T>
62-
// ClassDescription<T> subject(T &subject);
63-
//
64-
// template <class T>
65-
// ClassDescription<std::vector<T>> subject(std::initializer_list<T>
66-
// init_list);
67-
6859
void before_each(rule_block_t block);
6960
void before_all(rule_block_t block);
7061
void after_each(rule_block_t block);

include/let.hpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ class LetBase {
1313
bool delivered;
1414

1515
public:
16-
LetBase() : delivered(false) {}
16+
LetBase() noexcept : delivered(false) {}
1717
LetBase(const LetBase &copy) = default;
18-
void reset() { delivered = false; }
19-
bool has_result() { return delivered; }
18+
constexpr void reset() noexcept { delivered = false; }
19+
constexpr const bool has_result() noexcept { return this->delivered; }
20+
constexpr const bool has_result() const noexcept { return this->delivered; }
2021
};
2122

2223
template <typename T>
@@ -26,19 +27,23 @@ class Let : public LetBase {
2627

2728
block_t body;
2829

30+
void exec();
31+
2932
public:
30-
explicit Let(block_t body) : LetBase(), body(body) {}
33+
explicit Let(block_t body) noexcept : LetBase(), body(body) {}
3134

3235
T *operator->() {
3336
value();
3437
return result.operator->();
3538
}
3639

37-
T &operator*() & { return value(); }
38-
void exec();
40+
constexpr T &operator*() & { return value(); }
41+
constexpr const T &operator*() const & { return value(); }
42+
3943
T &value()&;
4044
};
4145

46+
/** @brief Executes the block of the let statment */
4247
template <typename T>
4348
void Let<T>::exec() {
4449
if (!delivered) {
@@ -47,6 +52,10 @@ void Let<T>::exec() {
4752
}
4853
}
4954

55+
/**
56+
* @brief Get the value contained in the Let
57+
* @return a reference to the returned object of the let statement
58+
*/
5059
template <typename T>
5160
T &Let<T>::value() & {
5261
exec();

include/result.hpp

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,56 +12,58 @@ namespace CppSpec {
1212
class Result {
1313
const bool value;
1414
std::string message;
15-
explicit Result(bool value, std::string message = "")
16-
: value(value), message(message) {}
15+
explicit Result(bool value, std::string message = "") noexcept
16+
: value(value),
17+
message(message) {}
1718

1819
public:
1920
// Default destructor
2021
virtual ~Result() = default;
2122

22-
// Move constructor/operator
23-
Result(Result &&) = default;
24-
Result &operator=(Result &&) = default;
25-
2623
// Copy constructor/operator
2724
Result(const Result &) = default;
2825
Result &operator=(const Result &) = default;
2926

30-
/*--------- Message helper functions -------------*/
31-
const std::string get_message() { return message; }
32-
const std::string get_message() const { return message; }
33-
Result &set_message(std::string message);
27+
// Move constructor/operator
28+
Result(Result &&) = default;
29+
Result &operator=(Result &&) = default;
3430

3531
/*--------- Status helper functions --------------*/
36-
const bool get_status() { return value; }
37-
const bool get_status() const { return value; }
32+
constexpr const bool get_status() noexcept { return value; }
33+
constexpr const bool get_status() const noexcept { return value; }
3834

39-
operator bool() { return this->get_status(); }
35+
constexpr operator bool() noexcept { return this->get_status(); }
36+
constexpr operator bool() const noexcept { return this->get_status(); }
37+
38+
/*--------- Message helper functions -------------*/
39+
const std::string get_message() noexcept { return message; }
40+
const std::string get_message() const noexcept { return message; }
41+
Result &set_message(std::string message) noexcept;
4042

4143
/*--------- Explicit constructor functions -------*/
42-
static Result success();
43-
static Result failure();
44-
static Result success_with(std::string success_message);
45-
static Result failure_with(std::string failure_message);
44+
static Result success() noexcept;
45+
static Result failure() noexcept;
46+
static Result success_with(std::string success_message) noexcept;
47+
static Result failure_with(std::string failure_message) noexcept;
4648

4749
/*-------------- Friend functions ----------------*/
4850

4951
// Stream operator
5052
friend std::ostream &operator<<(std::ostream &os, const Result &res);
5153
};
5254

53-
inline Result &Result::set_message(std::string message) {
55+
inline Result &Result::set_message(std::string message) noexcept {
5456
this->message = message;
5557
return *this;
5658
}
5759

58-
inline Result Result::success() { return Result(true); }
59-
inline Result Result::success_with(std::string success_message) {
60+
inline Result Result::success() noexcept { return Result(true); }
61+
inline Result Result::success_with(std::string success_message) noexcept {
6062
return Result(true, success_message);
6163
}
6264

63-
inline Result Result::failure() { return Result(false); }
64-
inline Result Result::failure_with(std::string failure_message) {
65+
inline Result Result::failure() noexcept { return Result(false); }
66+
inline Result Result::failure_with(std::string failure_message) noexcept {
6567
return Result(false, failure_message);
6668
}
6769

include/runnable.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ namespace CppSpec {
1515
*/
1616
class Runnable : public Child {
1717
public:
18-
Runnable() {}
19-
explicit Runnable(Child &parent) : Child(parent) {}
20-
explicit Runnable(Child *parent) : Child(parent) {}
21-
explicit Runnable(const Child *parent) : Child(parent) {}
18+
Runnable() = default;
19+
explicit Runnable(Child &parent) noexcept : Child(parent) {}
20+
explicit Runnable(Child *parent) noexcept : Child(parent) {}
21+
explicit Runnable(const Child *parent) noexcept : Child(parent) {}
2222
virtual Result run(Formatters::BaseFormatter &printer) = 0;
2323
};
2424

include/runner.hpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@
1010

1111
namespace CppSpec {
1212

13+
/**
14+
* @brief A collection of Descriptions that are run in sequence
15+
*/
1316
class Runner {
1417
std::list<Description *> specs;
1518
Formatters::BaseFormatter &formatter;
1619

1720
public:
1821
typedef std::function<void(Runner &)> spec_group;
19-
explicit Runner(Formatters::BaseFormatter &formatter = Formatters::progress)
20-
: formatter(formatter) {}
22+
explicit Runner(Formatters::BaseFormatter &formatter =
23+
Formatters::progress) noexcept : formatter(formatter) {}
2124

2225
template <typename T>
2326
Runner &add_spec(ClassDescription<T> &spec);
@@ -26,12 +29,24 @@ class Runner {
2629
Result exec();
2730
};
2831

32+
/**
33+
* @brief Add a describe_a suite to the list of suites to run
34+
*
35+
* @param spec the spec to be added
36+
* @return a reference to the modified Runner
37+
*/
2938
template <typename T>
3039
Runner &Runner::add_spec(ClassDescription<T> &spec) {
3140
specs.push_back(&spec);
3241
return *this;
3342
}
3443

44+
/**
45+
* @brief Add a Description object
46+
*
47+
* @param spec the spec to be added
48+
* @return a reference to the modified Runner
49+
*/
3550
inline Runner &Runner::add_spec(Description &spec) {
3651
specs.push_back(&spec);
3752
return *this;

spec/runner.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ extern std::function<void(CppSpec::Runner &)> expectation_spec_group,
55
describe_a_spec_group, describe_spec_group;
66

77
int main(void) {
8-
CppSpec::Runner runner(CppSpec::Formatters::verbose);
8+
CppSpec::Runner runner(CppSpec::Formatters::progress);
99
expectation_spec_group(runner);
1010
be_between_spec_group(runner);
1111
be_within_spec_group(runner);
@@ -14,4 +14,4 @@ int main(void) {
1414
describe_spec_group(runner);
1515

1616
return runner.exec() ? EXIT_SUCCESS : EXIT_FAILURE;
17-
}
17+
}

0 commit comments

Comments
 (0)