summaryrefslogtreecommitdiff
path: root/core/template_helpers.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/template_helpers.hpp')
-rw-r--r--core/template_helpers.hpp121
1 files changed, 121 insertions, 0 deletions
diff --git a/core/template_helpers.hpp b/core/template_helpers.hpp
new file mode 100644
index 0000000..01a27b5
--- /dev/null
+++ b/core/template_helpers.hpp
@@ -0,0 +1,121 @@
+#ifndef LY1b9novVl8oDseRTw8dH5lzpNo
+#define LY1b9novVl8oDseRTw8dH5lzpNo
+
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_empty.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_fundamental.hpp>
+#include <boost/mpl/unpack_args.hpp>
+#include <boost/mpl/list.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/deref.hpp>
+#include <boost/mpl/next.hpp>
+#include <boost/mpl/begin.hpp>
+#include <boost/mpl/end.hpp>
+#include <boost/mpl/front.hpp>
+#include <boost/mpl/pop_front.hpp>
+
+
+#define STATIC_ASSERT_IS_POWER_OF_TWO(x) BOOST_STATIC_ASSERT( !(x & (x-1)) );
+
+template<typename T, long long numerator, long long denominator = 1>
+struct StaticVal {
+ inline static const T value() { return T(numerator) / T(denominator); }
+};
+
+// forcing a type conversion of non-ptr types
+#define FORCE_CONV(Type, Val) (*(reinterpret_cast<Type *>(& Val)))
+
+// generate a constructor which fails when called
+// TODO (beauty): catch error after optimization, before runtime
+// (e.g. by linking to a forbidden symbol)
+#define GEN_ANYCAST_CTOR_3(name) \
+ template<class T1, class T2, class T3> name(T1 t1, T2 t2, T3 t3)
+
+// a void you may return
+struct Void {
+ typedef Void type; // for metaprogramming brainfucks
+ typedef Void con_arg_t;
+};
+
+// just to beautify some code
+struct BaseCase {};
+
+// prevent instanciation of default or unimplemented cases
+#define DO_NOT_INSTANCE(T) BOOST_STATIC_ASSERT((false && boost::is_same<T,T>::value));
+
+// forward decl of a function which will never exist (allows showing
+// errors at link time: later than DO_NOT_INSTANCE but before
+// assert(false)
+void oOoOo_LINK_TIME_ASSERTION_FAILED_oOoOo() __attribute__ ((noreturn));
+#define DO_NOT_CALL {oOoOo_LINK_TIME_ASSERTION_FAILED_oOoOo();}
+
+namespace UnpackTypeListImpl {
+
+using namespace boost::mpl;
+
+template<template<typename... T> class Tgt,
+ typename Iter, typename EndIter,
+ typename... NewList>
+struct Action {
+ typedef typename Action<Tgt,
+ typename next<Iter>::type, EndIter,
+ NewList...,
+ typename deref<Iter>::type
+ >::type type;
+};
+
+template<template<typename... T> class Tgt, typename EndIter, typename... List>
+struct Action<Tgt, EndIter, EndIter, List...> {
+ typedef Tgt<List...> type;
+};
+
+} // NS
+
+// unpack a boost::mpl sequence into a variadic type list
+template<template<typename... T> class Tgt,
+ typename Seq,
+ typename... NewList>
+struct UnpackTypeList {
+ typedef typename UnpackTypeListImpl
+ ::Action<Tgt,
+ typename boost::mpl::begin<Seq>::type,
+ typename boost::mpl::end<Seq>::type,
+ NewList...>::type type;
+};
+
+// create a unique class from a type, given a variadic garbage type
+// list; if the type is an empty struct it is not stored but created
+// upon every request
+// TODO: access functions (right now the stored values are only
+// accessed using outraging pointer casts)
+template<typename T, bool isEmpty, bool isFund, typename... Garbage> struct MakeUniqueImpl;
+
+template<typename T, typename... Garbage>
+struct MakeUnique {
+ typedef MakeUniqueImpl<T, boost::is_empty<T>::value,
+ boost::is_fundamental<T>::value, Garbage...> type;
+};
+
+template<typename T, typename... Garbage>
+struct MakeUniqueImpl<T, true, false, Garbage...> {
+ MakeUniqueImpl(const T &v) {}
+ MakeUniqueImpl(T &&v) {}
+ MakeUniqueImpl() = default;
+};
+
+template<typename T, typename... Garbage>
+struct MakeUniqueImpl<T, false, true, Garbage...> {
+ MakeUniqueImpl(const T &v) : v(v) {}
+ MakeUniqueImpl(T &&v) : v(v) {}
+ MakeUniqueImpl() = default;
+ T v;
+};
+
+template<typename T, typename... Garbage>
+struct MakeUniqueImpl<T, false, false, Garbage...> : protected T {
+ MakeUniqueImpl(T&& a) : T(std::move(a)) {}
+ MakeUniqueImpl() = default;
+};
+
+#endif // LY1b9novVl8oDseRTw8dH5lzpNo
contact: Jan Huwald // Impressum