diff options
author | Ben Longbons <b.r.longbons@gmail.com> | 2012-12-14 22:25:07 -0800 |
---|---|---|
committer | Ben Longbons <b.r.longbons@gmail.com> | 2012-12-15 19:41:53 -0800 |
commit | 4bd7eeec09629d3c0f900d42c899fe23c69e07b6 (patch) | |
tree | 4fbbfa45d9538cab7e1062f2c927297bb93ada0a /src/common/utils2.hpp | |
parent | 069f39e8a1ebee3e4a4ce8302d0099842876782b (diff) | |
download | tmwa-4bd7eeec09629d3c0f900d42c899fe23c69e07b6.tar.gz tmwa-4bd7eeec09629d3c0f900d42c899fe23c69e07b6.tar.bz2 tmwa-4bd7eeec09629d3c0f900d42c899fe23c69e07b6.tar.xz tmwa-4bd7eeec09629d3c0f900d42c899fe23c69e07b6.zip |
Prepare to trim skills
Diffstat (limited to 'src/common/utils2.hpp')
-rw-r--r-- | src/common/utils2.hpp | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/src/common/utils2.hpp b/src/common/utils2.hpp new file mode 100644 index 0000000..aef6f73 --- /dev/null +++ b/src/common/utils2.hpp @@ -0,0 +1,138 @@ +// included by utils.hpp as a porting aid. +// Eventually it will be promoted to one or more normal headers. + +#include <type_traits> +#include <iterator> + +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); + } +}; + +template<class T, class E> +class eptr +{ + T *_data; +public: + eptr(decltype(nullptr)=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; + } +}; + +template<class It> +class IteratorPair +{ + It b, e; +public: + IteratorPair(It b, It e) + : b(b), e(e) + {} + + It begin() { return b; } + It end() { return e; } +}; + +template<class It> +IteratorPair<It> iterator_pair(It b, It e) +{ + return {b, e}; +} + +#ifndef HAVE_STD_UNDERLYING_TYPE +// Note: you *must* correctly define/not define this - it conflicts! +namespace std +{ + 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; + }; +} +#endif // HAVE_STD_UNDERLYING_TYPE + +template<class E> +class EnumValueIterator +{ + typedef typename std::underlying_type<E>::type U; + E value; +public: + EnumValueIterator(E v) + : value(v) + {} + + E operator *() + { + return value; + } + EnumValueIterator& operator++ () + { + value = E(U(value) + 1); + return *this; + } + EnumValueIterator& operator-- () + { + value = E(U(value) - 1); + return *this; + } + friend bool operator == (EnumValueIterator l, EnumValueIterator r) + { + return l.value == r.value; + } + friend bool operator != (EnumValueIterator l, EnumValueIterator r) + { + return !(l == r); + } +}; + +template<class E> +IteratorPair<EnumValueIterator<E>> erange(E b, E e) +{ + return {b, e}; +} |