#ifndef TTR_ENUM_FUNCTIONS
#define TTR_ENUM_FUNCTIONS

#include <optional>
#include <string.h>
#include <type_traits>

template <typename T>
constexpr size_t enum_count(){
  return static_cast<size_t>(T::COUNT);
}

template <typename T>
using EnumNames = std::array<char const*,enum_count<T>()>;

//template <typename T>
//static constexpr EnumNames<T> enum_names;
//due to compile problems on macos static (above) is replaced with inline (below)

template <typename T>
inline constexpr EnumNames<T> enum_names;


template <typename T>
std::optional<T> enum_cast(unsigned int num){
  return static_cast<T>(num);
}

template <typename T>
std::optional<T> enum_cast(char const* name){
  unsigned int item = 0;
  for(item = 0; item < enum_count<T>(); item++){
    if(strcmp(name, enum_names<T>[item])==0)
      return enum_cast<T>(item);
  }
  return {};
}

template <typename T>
constexpr std::underlying_type_t<T> enum_value(T item){
  return static_cast<std::underlying_type_t<T>>(item);
}

template <typename T>
char const* enum_name(T item){
  return enum_names<T>[enum_value<T>(item)];
}

#endif // TTR_ENUM_FUNCTIONS
