diff options
author | ipknHama <ipknhama@gmail.com> | 2014-04-03 05:31:32 +0900 |
---|---|---|
committer | ipknHama <ipknhama@gmail.com> | 2014-04-03 08:29:22 +0900 |
commit | d533a619c99c5ead31e86afd14dd9b017c63a9ab (patch) | |
tree | 3afcd6fd4ddb83ea623fbba374a011ff40042659 /routing.h | |
parent | 5e5d69688435ffe8fc148af73fe33b029d9f6110 (diff) | |
download | crow-d533a619c99c5ead31e86afd14dd9b017c63a9ab.tar.gz crow-d533a619c99c5ead31e86afd14dd9b017c63a9ab.zip |
routing class working version
Diffstat (limited to 'routing.h')
-rw-r--r-- | routing.h | 110 |
1 files changed, 101 insertions, 9 deletions
@@ -1,6 +1,9 @@ #pragma once #include <cstdint> +#include <utility> +#include <string> +#include <tuple> #include "utility.h" @@ -8,32 +11,121 @@ namespace flask { namespace black_magic { - constexpr bool is_equ_n(StrWrap a, int ai, StrWrap b, int bi, int n) + constexpr bool is_equ_n(const_str a, int ai, const_str b, int bi, int n) { - return n == 0 ? true : a[ai] != b[bi] ? false : is_equ_n(a,ai+1,b,bi+1,n-1); + return + ai + n > a.size() || bi + n > b.size() + ? false : + n == 0 + ? true : + a[ai] != b[bi] + ? false : + is_equ_n(a,ai+1,b,bi+1,n-1); } - constexpr bool is_int(StrWrap s, int i) + constexpr bool is_int(const_str s, int i) { return is_equ_n(s, i, "<int>", 0, 5); } - constexpr bool is_str(StrWrap s, int i) + constexpr bool is_float(const_str s, int i) + { + return is_equ_n(s, i, "<float>", 0, 7) || + is_equ_n(s, i, "<double>", 0, 8); + } + + constexpr bool is_str(const_str s, int i) { return is_equ_n(s, i, "<str>", 0, 5); } - //constexpr ? parse_route(StrWrap s) - //{ - //return - //} + constexpr bool is_path(const_str s, int i) + { + return is_equ_n(s, i, "<path>", 0, 6); + } + + template <typename ...Args> + struct Caller + { + template <typename F> + void operator()(F f, Args... args) + { + f(args...); + } + }; + + + template <int N, typename ... Args> struct S; + template <int N, typename Arg, typename ... Args> struct S<N, Arg, Args...> { + static_assert(N <= 4+1, "too many routing arguments (maximum 5)"); + template <typename T> + using push = typename std::conditional<(N>4), S<N, Arg, Args...>, S<N+1, Arg, Args..., T>>::type; + using pop = S<N-1, Args...>; + }; + template <> struct S<0> + { + template <typename T> + using push = S<1, T>; + }; + + template <typename F, typename Set> + struct CallHelper; + template <typename F, int N, typename ...Args> + struct CallHelper<F, S<N, Args...>> + { + template <typename F1, typename ...Args1, typename = + decltype(std::declval<F1>()(std::declval<Args1>()...)) + > + static char __test(int); + + template <typename ...> + static int __test(...); + + static constexpr bool value = sizeof(__test<F, Args...>(0)) == sizeof(char); + }; + + static_assert(CallHelper<void(), S<0>>::value, ""); + static_assert(CallHelper<void(int), S<1, int>>::value, ""); + static_assert(!CallHelper<void(int), S<0>>::value, ""); + static_assert(!CallHelper<void(int), S<2, int, int>>::value, ""); + + template <typename F, + typename Set = S<0>> + constexpr bool validate_helper(const_str rule, unsigned i=0) + { + return + i == rule.size() + ? CallHelper<F, Set>::value : + is_int(rule, i) + ? validate_helper<F, typename Set::template push<int>>(rule, find_closing_tag(rule, i+1)+1) : + is_float(rule, i) + ? validate_helper<F, typename Set::template push<double>>(rule, find_closing_tag(rule, i+1)+1) : + is_str(rule, i) + ? validate_helper<F, typename Set::template push<std::string>>(rule, find_closing_tag(rule, i+1)+1) : + is_path(rule, i) + ? validate_helper<F, typename Set::template push<std::string>>(rule, find_closing_tag(rule, i+1)+1) : + validate_helper<F, Set>(rule, i+1) + ; + } + + static_assert(validate_helper<void()>("/"),""); + static_assert(validate_helper<void(int)>("/<int>"),""); + static_assert(!validate_helper<void()>("/<int>"),""); } class Router { public: - constexpr Router(black_magic::StrWrap s) + constexpr Router(black_magic::const_str rule) : rule(rule) + { + } + + template <typename F> + constexpr bool validate() const { + return black_magic::validate_helper<F>(rule); } + private: + black_magic::const_str rule; }; } |