diff options
author | Ben Longbons <b.r.longbons@gmail.com> | 2014-03-15 19:34:59 -0700 |
---|---|---|
committer | Ben Longbons <b.r.longbons@gmail.com> | 2014-03-16 18:58:48 -0700 |
commit | c812c92d1a1835f0bda783e709481188c8d92225 (patch) | |
tree | b401ede48a088ad1aaed88fe3b997cd26ff7ae08 /src/generic/enum.hpp | |
parent | de9ee1b9754af9d954487121947352f32d7ebb7e (diff) | |
download | tmwa-c812c92d1a1835f0bda783e709481188c8d92225.tar.gz tmwa-c812c92d1a1835f0bda783e709481188c8d92225.tar.bz2 tmwa-c812c92d1a1835f0bda783e709481188c8d92225.tar.xz tmwa-c812c92d1a1835f0bda783e709481188c8d92225.zip |
Clean up header organization
Diffstat (limited to 'src/generic/enum.hpp')
-rw-r--r-- | src/generic/enum.hpp | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/src/generic/enum.hpp b/src/generic/enum.hpp new file mode 100644 index 0000000..6f29981 --- /dev/null +++ b/src/generic/enum.hpp @@ -0,0 +1,170 @@ +#ifndef TMWA_GENERIC_ENUM_HPP +#define TMWA_GENERIC_ENUM_HPP + +# include "../sanity.hpp" + +# include <type_traits> + +# include "../compat/iter.hpp" + +template<class T, class E, E max> +struct earray +{ + // no ctor/dtor and one public member variable for easy initialization + T _data[size_t(max)]; + + T& operator[](E v) + { + return _data[size_t(v)]; + } + + const T& operator[](E v) const + { + return _data[size_t(v)]; + } + + T *begin() + { + return _data; + } + + T *end() + { + return _data + size_t(max); + } + + const T *begin() const + { + return _data; + } + + const T *end() const + { + return _data + size_t(max); + } + + friend bool operator == (const earray& l, const earray& r) + { + return std::equal(l.begin(), l.end(), r.begin()); + } + + friend bool operator != (const earray& l, const earray& r) + { + return !(l == r); + } +}; + +template<class T, class E> +class eptr +{ + T *_data; +public: + eptr(std::nullptr_t=nullptr) + : _data(nullptr) + {} + + template<E max> + eptr(earray<T, E, max>& arr) + : _data(arr._data) + {} + + T& operator [](E v) + { + return _data[size_t(v)]; + } + + explicit operator bool() + { + return _data; + } + + bool operator not() + { + return not _data; + } +}; + +// std::underlying_type isn't supported until gcc 4.7 +// this is a poor man's emulation +template<class E> +struct underlying_type +{ + static_assert(std::is_enum<E>::value, "Only enums have underlying type!"); + typedef typename std::conditional< + std::is_signed<E>::value, + typename std::make_signed<E>::type, + typename std::make_unsigned<E>::type + >::type type; +}; + +template<class E, bool=std::is_enum<E>::value> +struct remove_enum +{ + typedef E type; +}; +template<class E> +struct remove_enum<E, true> +{ + typedef typename underlying_type<E>::type type; +}; + + +# define ENUM_BITWISE_OPERATORS(E) \ +inline \ +E operator & (E l, E r) \ +{ \ + typedef underlying_type<E>::type U; \ + return E(U(l) & U(r)); \ +} \ +inline \ +E operator | (E l, E r) \ +{ \ + typedef underlying_type<E>::type U; \ + return E(U(l) | U(r)); \ +} \ +inline \ +E operator ^ (E l, E r) \ +{ \ + typedef underlying_type<E>::type U; \ + return E(U(l) ^ U(r)); \ +} \ +inline \ +E& operator &= (E& l, E r) \ +{ \ + return l = l & r; \ +} \ +inline \ +E& operator |= (E& l, E r) \ +{ \ + return l = l | r; \ +} \ +inline \ +E& operator ^= (E& l, E r) \ +{ \ + return l = l ^ r; \ +} \ +inline \ +E operator ~ (E r) \ +{ \ + return E(-1) ^ r; \ +} + +template<class E> +class EnumMath +{ + typedef typename underlying_type<E>::type U; +public: + static + E inced(E v) + { + return E(U(v) + 1); + } +}; + +template<class E> +IteratorPair<ValueIterator<E, EnumMath<E>>> erange(E b, E e) +{ + return {b, e}; +} + +#endif // TMWA_GENERIC_ENUM_HPP |