aboutsummaryrefslogtreecommitdiffstats
path: root/routing.h
diff options
context:
space:
mode:
authoripknHama <ipknhama@gmail.com>2014-04-03 05:31:32 +0900
committeripknHama <ipknhama@gmail.com>2014-04-03 08:29:22 +0900
commitd533a619c99c5ead31e86afd14dd9b017c63a9ab (patch)
tree3afcd6fd4ddb83ea623fbba374a011ff40042659 /routing.h
parent5e5d69688435ffe8fc148af73fe33b029d9f6110 (diff)
downloadcrow-d533a619c99c5ead31e86afd14dd9b017c63a9ab.tar.gz
crow-d533a619c99c5ead31e86afd14dd9b017c63a9ab.zip
routing class working version
Diffstat (limited to 'routing.h')
-rw-r--r--routing.h110
1 files changed, 101 insertions, 9 deletions
diff --git a/routing.h b/routing.h
index ca9c0ec..a150a4e 100644
--- a/routing.h
+++ b/routing.h
@@ -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;
};
}