-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdefines.hpp
112 lines (92 loc) · 3.37 KB
/
defines.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#ifndef MACRODEFINES
#define MACRODEFINES
#include <boost/preprocessor/seq/to_list.hpp>
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/preprocessor/list/to_seq.hpp>
#include <boost/preprocessor/list/for_each.hpp>
#include <boost/preprocessor/tuple/to_list.hpp>
#include <boost/preprocessor/list/append.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/variadic/elem.hpp>
#include <boost/preprocessor/facilities/expand.hpp>
#include <boost/preprocessor/array/enum.hpp>
#include <boost/preprocessor/array/size.hpp>
#include <boost/preprocessor/control/expr_iif.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/at.hpp>
#include <type_traits>
// fuck if I know.
#define BOOST_PP_TUPLE_REM_0() \
#define ENUMERATE(arr) \
BOOST_PP_ARRAY_ENUM(arr) \
#define STRINGIZE_SEQ2(N, S) \
BOOST_PP_EXPAND(BOOST_PP_SEQ_ELEM(N, S)) \
#define STRINGIZE_SEQ(N, S) \
BOOST_PP_STRINGIZE(STRINGIZE_SEQ2(N, S)) \
#define FUNCTIONRECORD(R, _, name) \
, \
FunctionWrapper<HASH(STRINGIZE_SEQ(1, name)), BOOST_PP_EXPAND(GET_TYPE_NAME(BOOST_PP_SEQ_ELEM(0, name)))>
#define CREATEWRAPPER(SEQ) \
BOOST_PP_EXPAND(CREATE_STRUCTS(NEWLIST)) \
typedef Wrapper< \
FunctionWrapper<0, int> \
BOOST_PP_LIST_FOR_EACH(FUNCTIONRECORD, _, SEQ) \
> wrapper; \
bool DIRECT_SUCCESS=false; \
#define BIGSWITCH(strString, args) \
[&strString, &DIRECT_SUCCESS](){ \
std::string& DIRECT_STRING = strString; \
unsigned long strHash = operator""_toHash(strString.c_str(), strString.length()); \
typedef std::result_of<GET_TYPE_NAME(BOOST_PP_SEQ_ELEM(0, BOOST_PP_LIST_FIRST(NEWLIST)))(int, float)>::type DIRECT_RETURN_TYPE; \
DIRECT_RETURN_TYPE DIRECT_RESULT{}; \
switch(strHash) { \
BOOST_PP_LIST_FOR_EACH(CASE, args, NEWLIST) \
default: \
DIRECT_DEFAULT: \
std::cout<<"No such handle"<<std::endl; \
break; \
} \
return DIRECT_RESULT; \
}() \
#define CASE(R, args, T) \
case HASH( STRINGIZE_SEQ(1, T) ): \
if( DIRECT_STRING == BOOST_PP_STRINGIZE(BOOST_PP_SEQ_ELEM(1, T))){ \
DIRECT_RESULT = \
wrapper::GetFunction< \
HASH(BOOST_PP_STRINGIZE(BOOST_PP_EXPAND(BOOST_PP_SEQ_ELEM(1, T)))) \
>{}( ENUMERATE(args) ); \
DIRECT_SUCCESS=true; \
} else { \
goto DIRECT_DEFAULT; \
} \
break; \
#define GET_TYPE_NAME(f) \
BOOST_PP_CAT(DIRECT_TYPE_, f) \
#define MAKE_TYPE(R, _, f) \
struct GET_TYPE_NAME(BOOST_PP_SEQ_ELEM(0, f)) { \
auto operator()(FORMAL_PARAMETERS) -> decltype(BOOST_PP_SEQ_ELEM(0, f)(ACTUAL_PARAMETERS)){ \
return BOOST_PP_SEQ_ELEM(0, f)(ACTUAL_PARAMETERS); \
} \
}; \
#define CREATE_STRUCTS(l) \
BOOST_PP_LIST_FOR_EACH(MAKE_TYPE, _, l) \
template<class first, class... rest> // first ignored intentionally so macros are easier.
struct Wrapper {
typedef boost::mpl::map<rest...> mp;
template<long hash>
using GetFunction = typename boost::mpl::at<mp, boost::mpl::long_<hash>>::type;
};
template<unsigned long l, class Function>
using FunctionWrapper = boost::mpl::pair<boost::mpl::long_<l>, Function>;
constexpr unsigned long operator "" _toHash ( const char* str, std::size_t length ) {
return (length>0)?
static_cast<unsigned long>(str[length-1]>='A'?str[length-1]-'A':(str[length-1]<'a'?str[length-1]-'0':str[length-1]-'a')) +
26*operator ""_toHash(str, length-1)
:0 ;
}
template<unsigned N>
constexpr unsigned long HASH(const char (&str) [N]) {
return operator""_toHash(str, N-1);
}
#endif