Skip to content

Instantly share code, notes, and snippets.

@plasma-effect
Created August 20, 2015 15:16
Show Gist options
  • Save plasma-effect/779df3e53cf5dc9d1618 to your computer and use it in GitHub Desktop.
Save plasma-effect/779df3e53cf5dc9d1618 to your computer and use it in GitHub Desktop.
#pragma once
// Copyright plasma-effect 2015
// Distributed under the Boost Software License, Version 1.0.
// (See http://www.boost.org/LICENSE_1_0.txt)
#include<type_traits>
#include<tuple>
namespace plasma
{
namespace lambda
{
namespace detail//for projection_t
{
constexpr int pow(int v, std::size_t p)
{
return (p == 0 ? 1 : (p == 1 ? v : (p == 2 ? v*v : (p % 2 == 0 ? pow(pow(v, p / 2), 2) : p*pow(pow(v, p / 2), 2)))));
}
template<int I, int... Is>struct char_to_int_i
{
static constexpr int run(int p)
{
return I*p + char_to_int_i<Is...>::run(p / 10);
}
};
template<int I>struct char_to_int_i<I>
{
static constexpr int run(int p)
{
return I;
}
};
template<bool F, int I>struct projection_i
{
static_assert(F, "projection_t error: few parameter");
template<class... Ts>static constexpr void* run(Ts&&...)
{
return nullptr;
}
};
template<int I>struct projection_i<true, I>
{
template<class T, class... Ts>static constexpr decltype(auto) run(T&&, Ts&&... vs)
{
return projection_i<true, I - 1>::run(std::forward<Ts>(vs)...);
}
};
template<>struct projection_i<true, 0>
{
template<class T, class... Ts>static constexpr decltype(auto) run(T&& v, Ts&&...)
{
return std::forward<T>(v);
}
};
}//detail for projection_t
template<int I>struct projection_t
{
constexpr projection_t(){}
constexpr projection_t(projection_t<I>const&){}
constexpr projection_t(projection_t<I>&&){}
~projection_t() = default;
template<class... Ts>constexpr decltype(auto) operator()(Ts&&... vs)const
{
return detail::projection_i<(I<sizeof...(Ts)), I>::run(std::forward<Ts>(vs)...);
}
};
template<char... Is>constexpr auto operator"" _proj()
{
return projection_t<detail::char_to_int_i<(Is - '0')...>::run(detail::pow(10, sizeof...(Is)-1))>{};
}
}//lambda
}//plasma

#What is コンパイル時ラムダ

#使いかた プロジェクトのリポジトリに投げ込んだりしてincludeする。

#リファレンス ##plasma::lambda

###operator"" _proj ####宣言

template<char... Is>constexpr auto operator"" _proj();

####What is constexprで第I番目の引数をstd::forwardする関数オブジェクトを返す。
ただしIは0-originで返り値の型はdecltype(auto)で定義される。
また引数の数はI+1以上でなければならない ####例

using namespace plasma::lambda;
constexpr auto _ = 1_proj;
constexpr int v = _(0, 1, 2);
static_assert(v == 1, "");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment