Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Completes constexpr-enabling of morph::vec<> #189

Merged
merged 5 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/ref/coremaths/vec.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ Header file: [morph/vec.h](https://github.com/ABRG-Models/morphologica/blob/main

`morph::vec` is a fixed-size mathematical vector class. It derives
from `std::array` and can be used in much the same way as its STL
parent. It has iterators and you can apply STL algorithms.
parent. It has iterators and you can apply STL algorithms. It is
constexpr-capable, meaning that it can be incorporated into constexpr
functions to do compile-time maths.

```c++
namespace morph {
Expand Down
27 changes: 10 additions & 17 deletions morph/range.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,27 @@
* A tiny container class to hold the min and max of a range. I wanted a common type in
* which to return minmax values for use in morph::vec and morph::vvec. An option would
* have been an std::array, but I prefer this, as vvec doesn't otherwise need to include
* <array>.
* <array>. range can be used in constexpr functions.
*
* Author: Seb James
* Date: Sept. 2023.
*/

#include <string>
#include <sstream>
#include <ostream>
#include <limits>

namespace morph {

// Forward declare the class and stream operator
template <typename T> struct range;
template <typename T> std::ostream& operator<< (std::ostream&, const range<T>&);

// range is a constexpr-friendly literal type
template <typename T>
struct range
{
range() {}
range (const T& _min, const T& _max) : min(_min), max(_max) {}
constexpr range() {}
constexpr range (const T& _min, const T& _max) : min(_min), max(_max) {}

// The minimum
T min = T{0};
Expand All @@ -41,38 +41,31 @@ namespace morph {
// r.search_init();
// for (auto d : data) { r.update (d); }
// std::cout << "The range of values in data was: " << r << std::endl;
void search_init()
constexpr void search_init()
{
this->min = std::numeric_limits<T>::max();
this->max = std::numeric_limits<T>::lowest();
}

// Extend the range to include the given datum
void update (const T& d)
constexpr void update (const T& d)
{
this->min = d < this->min ? d : this->min;
this->max = d > this->max ? d : this->max;
}

// Does the range include v?
bool includes (const T& v) { return (v <= this->max && v >= this->min); }

// Output a string with notation "[min, max]" to indicate a closed interval
std::string str() const
{
std::stringstream ss;
ss << "[" << this->min << ", " << this->max << "]";
return ss.str();
}
constexpr bool includes (const T& v) { return (v <= this->max && v >= this->min); }

// Overload the stream output operator
friend std::ostream& operator<< <T> (std::ostream& os, const range<T>& r);
};

// Output a string with notation "[min, max]" to indicate a closed interval
template <typename T>
std::ostream& operator<< (std::ostream& os, const range<T>& r)
{
os << r.str();
os << "[" << r.min << ", " << r.max << "]";
return os;
}

Expand Down
Loading