Skip to content

Commit

Permalink
colors slightly less weird
Browse files Browse the repository at this point in the history
  • Loading branch information
thorstink committed Oct 15, 2024
1 parent 894c3d3 commit 797b3a9
Showing 1 changed file with 54 additions and 75 deletions.
129 changes: 54 additions & 75 deletions symmetri/include/symmetri/colors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,90 +105,66 @@ namespace symmetri {
*
*/
class Token {
const static size_t kMaxTokenColors =
100; ///< Maximum amount of different colors
size_t idx; ///< A numerical id ("color") for this particular token
inline static std::array<const char*, kMaxTokenColors> v{
NULL}; ///< The human read-able string representation of the "color" is
///< stored in this buffer using the numerical id as index.

protected:
/**
* @brief Creates a Token with a unique numerical id and a string
* representation based on the name of the argument-type at compile-time.
*
* @tparam T the type representing the token-color
*/
template <class T>
constexpr Token(T* const) : idx(sym_impl::unique_id<T>()) {
static_assert(sym_impl::unique_id<T>() < v.size(),
"There can only be 100 different token-colors.");
v[idx] = sym_impl::type_name<T>().data();
}

public:
/**
* @brief Construct a new Token object from a string at run-time. A unique id
* is generated and if it fails it will exit the application through a failing
* assert.
*
* @param s string-representation of the color
*/
Token(const char* s)
: idx([&]() -> size_t {
static size_t i = 0;
auto it = std::find(v.cbegin(), v.cend(), s);
if (it == std::cend(v)) {
i++;
return v.size() - i;
} else {
return std::distance(v.cbegin(), it);
}
}()) {
if (std::find(v.cbegin(), v.cend(), s) == std::cend(v)) {
assert(v[idx] == NULL && "There can only be 100 different token-colors.");
v[idx] = strdup(s);
}
}

Token() = delete;

/**
* @brief Get a list of all the colors
*
* @return std::vector<const char *>
*/
static std::vector<const char*> getColors() {
std::vector<const char*> colors;
colors.reserve(v.size());
std::copy_if(v.begin(), v.end(), std::back_inserter(colors),
[](const auto& color) { return color != NULL; });
return colors;
std::vector<const char*> _colors;
_colors.reserve(colors.size());
std::copy_if(colors.begin(), colors.end(), std::back_inserter(_colors),
[](const auto& color) { return color != nullptr; });
return _colors;
}

constexpr const auto& toString() const { return colors[id]; }

template <class T>
constexpr bool operator==(const T& t) const {
return id == t.id;
}

constexpr bool operator<(const Token& rhs) const {
return idx < rhs.toIndex();
return id < rhs.toIndex();
}

constexpr bool operator>(const Token& rhs) const {
return idx > rhs.toIndex();
return id > rhs.toIndex();
}
/**
* @brief returns the unique index for this color.
*
* @return constexpr size_t
*/
constexpr size_t toIndex() const { return idx; }
constexpr int toIndex() const { return id; }

constexpr Token(const char* _id)
: id([_id]() -> int {
const auto it =
std::find_if(colors.cbegin(), colors.cend(), [=](const char* s) {
return s != nullptr && 0 == strcmp(_id, s);
});
if (it == colors.cend()) {
const auto nullptr_it =
std::find(colors.cbegin(), colors.cend(), nullptr);
assert(nullptr_it != colors.cend() &&
"There can only be kMaxTokenColors different token-colors.");
const auto idx = std::distance(colors.cbegin(), nullptr_it);
colors[idx] = strdup(_id);
return idx;
} else {
return std::distance(colors.cbegin(), it);
}
}()) {}

/**
* @brief returns the string-representation for this color.
*
* @return constexpr const auto&
*/
constexpr auto toString() const { return v[idx]; }
constexpr bool operator==(const Token& c) const { return idx == c.idx; }
template <class T>
constexpr bool operator==(const T&) const {
return idx == sym_impl::unique_id<T>();
}
protected:
const static size_t kMaxTokenColors =
100; ///< Maximum amount of different colors
constexpr Token(const char* id, const int idx) : id(idx) { colors[idx] = id; }
inline static std::array<const char*, kMaxTokenColors> colors = {nullptr};
int id;
};

} // namespace symmetri
Expand All @@ -206,15 +182,18 @@ struct std::hash<symmetri::Token> {
* end up in the symmetri namespace.
*
*/
#define CREATE_CUSTOM_TOKEN(name) \
namespace symmetri { \
struct name : public Token { \
constexpr name() : Token(this) {} \
constexpr bool operator==(const Token& c) const { \
return toIndex() == c.toIndex(); \
} \
}; \
static inline name name; \
#define CREATE_CUSTOM_TOKEN(name) \
namespace symmetri { \
struct name : public Token { \
constexpr name() \
: Token(sym_impl::type_name<name>().data(), \
sym_impl::unique_id<name>()) { \
static_assert( \
sym_impl::unique_id<name>() < kMaxTokenColors, \
"There can only be kMaxTokenColors different token-colors."); \
} \
}; \
static inline name name; \
}

CREATE_CUSTOM_TOKEN(Scheduled)
Expand Down

0 comments on commit 797b3a9

Please sign in to comment.