aboutsummaryrefslogtreecommitdiffstats
path: root/include/utility.h
diff options
context:
space:
mode:
authoripknHama <ipknhama@gmail.com>2016-09-21 23:11:06 +0900
committeripknHama <ipknhama@gmail.com>2016-09-21 23:11:06 +0900
commit3081e4e1a82a4efd8feff68850c4cc04af230cd7 (patch)
tree3ad16ef2e940abd2d47c4ac3ca224365387b7f37 /include/utility.h
parent8b04940d2f28290451db439ad29155a0b8771ba3 (diff)
downloadcrow-3081e4e1a82a4efd8feff68850c4cc04af230cd7.tar.gz
crow-3081e4e1a82a4efd8feff68850c4cc04af230cd7.zip
Cleanup include folder into crow subfolder
- only crow.h is exposed now
Diffstat (limited to 'include/utility.h')
-rw-r--r--include/utility.h548
1 files changed, 0 insertions, 548 deletions
diff --git a/include/utility.h b/include/utility.h
deleted file mode 100644
index 26ca151..0000000
--- a/include/utility.h
+++ /dev/null
@@ -1,548 +0,0 @@
-#pragma once
-
-#include <cstdint>
-#include <stdexcept>
-#include <tuple>
-#include <type_traits>
-#include <cstring>
-#include <functional>
-#include <string>
-
-#include "settings.h"
-
-namespace crow
-{
- namespace black_magic
- {
-#ifndef CROW_MSVC_WORKAROUND
- struct OutOfRange
- {
- OutOfRange(unsigned /*pos*/, unsigned /*length*/) {}
- };
- constexpr unsigned requires_in_range( unsigned i, unsigned len )
- {
- return i >= len ? throw OutOfRange(i, len) : i;
- }
-
- class const_str
- {
- const char * const begin_;
- unsigned size_;
-
- public:
- template< unsigned N >
- constexpr const_str( const char(&arr)[N] ) : begin_(arr), size_(N - 1) {
- static_assert( N >= 1, "not a string literal");
- }
- constexpr char operator[]( unsigned i ) const {
- return requires_in_range(i, size_), begin_[i];
- }
-
- constexpr operator const char *() const {
- return begin_;
- }
-
- constexpr const char* begin() const { return begin_; }
- constexpr const char* end() const { return begin_ + size_; }
-
- constexpr unsigned size() const {
- return size_;
- }
- };
-
- constexpr unsigned find_closing_tag(const_str s, unsigned p)
- {
- return s[p] == '>' ? p : find_closing_tag(s, p+1);
- }
-
- constexpr bool is_valid(const_str s, unsigned i = 0, int f = 0)
- {
- return
- i == s.size()
- ? f == 0 :
- f < 0 || f >= 2
- ? false :
- s[i] == '<'
- ? is_valid(s, i+1, f+1) :
- s[i] == '>'
- ? is_valid(s, i+1, f-1) :
- is_valid(s, i+1, f);
- }
-
- constexpr bool is_equ_p(const char* a, const char* b, unsigned n)
- {
- return
- *a == 0 && *b == 0 && n == 0
- ? true :
- (*a == 0 || *b == 0)
- ? false :
- n == 0
- ? true :
- *a != *b
- ? false :
- is_equ_p(a+1, b+1, n-1);
- }
-
- constexpr bool is_equ_n(const_str a, unsigned ai, const_str b, unsigned bi, unsigned n)
- {
- 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(const_str s, unsigned i)
- {
- return is_equ_n(s, i, "<int>", 0, 5);
- }
-
- constexpr bool is_uint(const_str s, unsigned i)
- {
- return is_equ_n(s, i, "<uint>", 0, 6);
- }
-
- constexpr bool is_float(const_str s, unsigned 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, unsigned i)
- {
- return is_equ_n(s, i, "<str>", 0, 5) ||
- is_equ_n(s, i, "<string>", 0, 8);
- }
-
- constexpr bool is_path(const_str s, unsigned i)
- {
- return is_equ_n(s, i, "<path>", 0, 6);
- }
-#endif
- template <typename T>
- struct parameter_tag
- {
- static const int value = 0;
- };
-#define CROW_INTERNAL_PARAMETER_TAG(t, i) \
-template <> \
-struct parameter_tag<t> \
-{ \
- static const int value = i; \
-}
- CROW_INTERNAL_PARAMETER_TAG(int, 1);
- CROW_INTERNAL_PARAMETER_TAG(char, 1);
- CROW_INTERNAL_PARAMETER_TAG(short, 1);
- CROW_INTERNAL_PARAMETER_TAG(long, 1);
- CROW_INTERNAL_PARAMETER_TAG(long long, 1);
- CROW_INTERNAL_PARAMETER_TAG(unsigned int, 2);
- CROW_INTERNAL_PARAMETER_TAG(unsigned char, 2);
- CROW_INTERNAL_PARAMETER_TAG(unsigned short, 2);
- CROW_INTERNAL_PARAMETER_TAG(unsigned long, 2);
- CROW_INTERNAL_PARAMETER_TAG(unsigned long long, 2);
- CROW_INTERNAL_PARAMETER_TAG(double, 3);
- CROW_INTERNAL_PARAMETER_TAG(std::string, 4);
-#undef CROW_INTERNAL_PARAMETER_TAG
- template <typename ... Args>
- struct compute_parameter_tag_from_args_list;
-
- template <>
- struct compute_parameter_tag_from_args_list<>
- {
- static const int value = 0;
- };
-
- template <typename Arg, typename ... Args>
- struct compute_parameter_tag_from_args_list<Arg, Args...>
- {
- static const int sub_value =
- compute_parameter_tag_from_args_list<Args...>::value;
- static const int value =
- parameter_tag<typename std::decay<Arg>::type>::value
- ? sub_value* 6 + parameter_tag<typename std::decay<Arg>::type>::value
- : sub_value;
- };
-
- static inline bool is_parameter_tag_compatible(uint64_t a, uint64_t b)
- {
- if (a == 0)
- return b == 0;
- if (b == 0)
- return a == 0;
- int sa = a%6;
- int sb = a%6;
- if (sa == 5) sa = 4;
- if (sb == 5) sb = 4;
- if (sa != sb)
- return false;
- return is_parameter_tag_compatible(a/6, b/6);
- }
-
- static inline unsigned find_closing_tag_runtime(const char* s, unsigned p)
- {
- return
- s[p] == 0
- ? throw std::runtime_error("unmatched tag <") :
- s[p] == '>'
- ? p : find_closing_tag_runtime(s, p + 1);
- }
-
- static inline uint64_t get_parameter_tag_runtime(const char* s, unsigned p = 0)
- {
- return
- s[p] == 0
- ? 0 :
- s[p] == '<' ? (
- std::strncmp(s+p, "<int>", 5) == 0
- ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 1 :
- std::strncmp(s+p, "<uint>", 6) == 0
- ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 2 :
- (std::strncmp(s+p, "<float>", 7) == 0 ||
- std::strncmp(s+p, "<double>", 8) == 0)
- ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 3 :
- (std::strncmp(s+p, "<str>", 5) == 0 ||
- std::strncmp(s+p, "<string>", 8) == 0)
- ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 4 :
- std::strncmp(s+p, "<path>", 6) == 0
- ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 5 :
- throw std::runtime_error("invalid parameter type")
- ) :
- get_parameter_tag_runtime(s, p+1);
- }
-#ifndef CROW_MSVC_WORKAROUND
- constexpr uint64_t get_parameter_tag(const_str s, unsigned p = 0)
- {
- return
- p == s.size()
- ? 0 :
- s[p] == '<' ? (
- is_int(s, p)
- ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 1 :
- is_uint(s, p)
- ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 2 :
- is_float(s, p)
- ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 3 :
- is_str(s, p)
- ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 4 :
- is_path(s, p)
- ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 5 :
- throw std::runtime_error("invalid parameter type")
- ) :
- get_parameter_tag(s, p+1);
- }
-#endif
-
- template <typename ... T>
- struct S
- {
- template <typename U>
- using push = S<U, T...>;
- template <typename U>
- using push_back = S<T..., U>;
- template <template<typename ... Args> class U>
- using rebind = U<T...>;
- };
-template <typename F, typename Set>
- struct CallHelper;
- template <typename F, typename ...Args>
- struct CallHelper<F, S<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);
- };
-
-
- template <int N>
- struct single_tag_to_type
- {
- };
-
- template <>
- struct single_tag_to_type<1>
- {
- using type = int64_t;
- };
-
- template <>
- struct single_tag_to_type<2>
- {
- using type = uint64_t;
- };
-
- template <>
- struct single_tag_to_type<3>
- {
- using type = double;
- };
-
- template <>
- struct single_tag_to_type<4>
- {
- using type = std::string;
- };
-
- template <>
- struct single_tag_to_type<5>
- {
- using type = std::string;
- };
-
-
- template <uint64_t Tag>
- struct arguments
- {
- using subarguments = typename arguments<Tag/6>::type;
- using type =
- typename subarguments::template push<typename single_tag_to_type<Tag%6>::type>;
- };
-
- template <>
- struct arguments<0>
- {
- using type = S<>;
- };
-
- template <typename ... T>
- struct last_element_type
- {
- using type = typename std::tuple_element<sizeof...(T)-1, std::tuple<T...>>::type;
- };
-
-
- template <>
- struct last_element_type<>
- {
- };
-
-
- // from http://stackoverflow.com/questions/13072359/c11-compile-time-array-with-logarithmic-evaluation-depth
- template<class T> using Invoke = typename T::type;
-
- template<unsigned...> struct seq{ using type = seq; };
-
- template<class S1, class S2> struct concat;
-
- template<unsigned... I1, unsigned... I2>
- struct concat<seq<I1...>, seq<I2...>>
- : seq<I1..., (sizeof...(I1)+I2)...>{};
-
- template<class S1, class S2>
- using Concat = Invoke<concat<S1, S2>>;
-
- template<unsigned N> struct gen_seq;
- template<unsigned N> using GenSeq = Invoke<gen_seq<N>>;
-
- template<unsigned N>
- struct gen_seq : Concat<GenSeq<N/2>, GenSeq<N - N/2>>{};
-
- template<> struct gen_seq<0> : seq<>{};
- template<> struct gen_seq<1> : seq<0>{};
-
- template <typename Seq, typename Tuple>
- struct pop_back_helper;
-
- template <unsigned ... N, typename Tuple>
- struct pop_back_helper<seq<N...>, Tuple>
- {
- template <template <typename ... Args> class U>
- using rebind = U<typename std::tuple_element<N, Tuple>::type...>;
- };
-
- template <typename ... T>
- struct pop_back //: public pop_back_helper<typename gen_seq<sizeof...(T)-1>::type, std::tuple<T...>>
- {
- template <template <typename ... Args> class U>
- using rebind = typename pop_back_helper<typename gen_seq<sizeof...(T)-1>::type, std::tuple<T...>>::template rebind<U>;
- };
-
- template <>
- struct pop_back<>
- {
- template <template <typename ... Args> class U>
- using rebind = U<>;
- };
-
- // from http://stackoverflow.com/questions/2118541/check-if-c0x-parameter-pack-contains-a-type
- template < typename Tp, typename... List >
- struct contains : std::true_type {};
-
- template < typename Tp, typename Head, typename... Rest >
- struct contains<Tp, Head, Rest...>
- : std::conditional< std::is_same<Tp, Head>::value,
- std::true_type,
- contains<Tp, Rest...>
- >::type {};
-
- template < typename Tp >
- struct contains<Tp> : std::false_type {};
-
- template <typename T>
- struct empty_context
- {
- };
-
- template <typename T>
- struct promote
- {
- using type = T;
- };
-
-#define CROW_INTERNAL_PROMOTE_TYPE(t1, t2) \
- template<> \
- struct promote<t1> \
- { \
- using type = t2; \
- }
-
- CROW_INTERNAL_PROMOTE_TYPE(char, int64_t);
- CROW_INTERNAL_PROMOTE_TYPE(short, int64_t);
- CROW_INTERNAL_PROMOTE_TYPE(int, int64_t);
- CROW_INTERNAL_PROMOTE_TYPE(long, int64_t);
- CROW_INTERNAL_PROMOTE_TYPE(long long, int64_t);
- CROW_INTERNAL_PROMOTE_TYPE(unsigned char, uint64_t);
- CROW_INTERNAL_PROMOTE_TYPE(unsigned short, uint64_t);
- CROW_INTERNAL_PROMOTE_TYPE(unsigned int, uint64_t);
- CROW_INTERNAL_PROMOTE_TYPE(unsigned long, uint64_t);
- CROW_INTERNAL_PROMOTE_TYPE(unsigned long long, uint64_t);
- CROW_INTERNAL_PROMOTE_TYPE(float, double);
-#undef CROW_INTERNAL_PROMOTE_TYPE
-
- template <typename T>
- using promote_t = typename promote<T>::type;
-
- } // namespace black_magic
-
- namespace detail
- {
-
- template <class T, std::size_t N, class... Args>
- struct get_index_of_element_from_tuple_by_type_impl
- {
- static constexpr auto value = N;
- };
-
- template <class T, std::size_t N, class... Args>
- struct get_index_of_element_from_tuple_by_type_impl<T, N, T, Args...>
- {
- static constexpr auto value = N;
- };
-
- template <class T, std::size_t N, class U, class... Args>
- struct get_index_of_element_from_tuple_by_type_impl<T, N, U, Args...>
- {
- static constexpr auto value = get_index_of_element_from_tuple_by_type_impl<T, N + 1, Args...>::value;
- };
-
- } // namespace detail
-
- namespace utility
- {
- template <class T, class... Args>
- T& get_element_by_type(std::tuple<Args...>& t)
- {
- return std::get<detail::get_index_of_element_from_tuple_by_type_impl<T, 0, Args...>::value>(t);
- }
-
- template<typename T>
- struct function_traits;
-
-#ifndef CROW_MSVC_WORKAROUND
- template<typename T>
- struct function_traits : public function_traits<decltype(&T::operator())>
- {
- using parent_t = function_traits<decltype(&T::operator())>;
- static const size_t arity = parent_t::arity;
- using result_type = typename parent_t::result_type;
- template <size_t i>
- using arg = typename parent_t::template arg<i>;
-
- };
-#endif
-
- template<typename ClassType, typename R, typename ...Args>
- struct function_traits<R(ClassType::*)(Args...) const>
- {
- static const size_t arity = sizeof...(Args);
-
- typedef R result_type;
-
- template <size_t i>
- using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
- };
-
- template<typename ClassType, typename R, typename ...Args>
- struct function_traits<R(ClassType::*)(Args...)>
- {
- static const size_t arity = sizeof...(Args);
-
- typedef R result_type;
-
- template <size_t i>
- using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
- };
-
- template<typename R, typename ...Args>
- struct function_traits<std::function<R(Args...)>>
- {
- static const size_t arity = sizeof...(Args);
-
- typedef R result_type;
-
- template <size_t i>
- using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
- };
-
- inline static std::string base64encode(const char* data, size_t size, const char* key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
- {
- std::string ret;
- ret.resize((size+2) / 3 * 4);
- auto it = ret.begin();
- while(size >= 3)
- {
- *it++ = key[(((unsigned char)*data)&0xFC)>>2];
- unsigned char h = (((unsigned char)*data++) & 0x03) << 4;
- *it++ = key[h|((((unsigned char)*data)&0xF0)>>4)];
- h = (((unsigned char)*data++) & 0x0F) << 2;
- *it++ = key[h|((((unsigned char)*data)&0xC0)>>6)];
- *it++ = key[((unsigned char)*data++)&0x3F];
-
- size -= 3;
- }
- if (size == 1)
- {
- *it++ = key[(((unsigned char)*data)&0xFC)>>2];
- unsigned char h = (((unsigned char)*data++) & 0x03) << 4;
- *it++ = key[h];
- *it++ = '=';
- *it++ = '=';
- }
- else if (size == 2)
- {
- *it++ = key[(((unsigned char)*data)&0xFC)>>2];
- unsigned char h = (((unsigned char)*data++) & 0x03) << 4;
- *it++ = key[h|((((unsigned char)*data)&0xF0)>>4)];
- h = (((unsigned char)*data++) & 0x0F) << 2;
- *it++ = key[h];
- *it++ = '=';
- }
- return ret;
- }
-
- inline static std::string base64encode_urlsafe(const char* data, size_t size)
- {
- return base64encode(data, size, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_");
- }
-
-
- } // namespace utility
-}