Skip to content

Instantly share code, notes, and snippets.

@Nekotekina
Created September 20, 2018 14:09
Show Gist options
  • Save Nekotekina/cc913bbd2386c593fe4beb3da9d1b3db to your computer and use it in GitHub Desktop.
Save Nekotekina/cc913bbd2386c593fe4beb3da9d1b3db to your computer and use it in GitHub Desktop.
const_v<> template variable
// Helper template
template <auto V>
struct const_value
{
static constexpr auto value = V;
constexpr operator decltype(V)() const noexcept
{
return V;
}
constexpr decltype(V) operator ()() const
{
return V;
}
};
// Specialize for function pointers
template <typename R, typename... Args, R(*F)(Args...)>
struct const_value<F>
{
static constexpr auto value = F;
constexpr operator decltype(F)() const noexcept
{
return F;
}
constexpr R operator ()(Args&&... args) const
{
return F(std::forward<Args>(args)...);
}
};
// Specialize for pointer to member function
template <typename R, typename B, typename... Args, R(B::*M)(Args...)>
struct const_value<M>
{
static constexpr auto value = M;
constexpr operator decltype(M)() const noexcept
{
return M;
}
constexpr R operator ()(B& base, Args&&... args) const
{
return (base.*M)(std::forward<Args>(args)...);
}
};
// Specialize for pointer to const member function
template <typename R, typename B, typename... Args, R(B::*M)(Args...) const>
struct const_value<M>
{
static constexpr auto value = M;
constexpr operator decltype(M)() const noexcept
{
return M;
}
constexpr R operator ()(const B& base, Args&&... args) const
{
return (base.*M)(std::forward<Args>(args)...);
}
};
// Specialize for pointer to data member
template <typename R, typename B, R B::* M>
struct const_value<M>
{
static constexpr auto value = M;
constexpr operator decltype(M)() const noexcept
{
return M;
}
constexpr R operator ()(const B& base) const
{
return (base.*M);
}
constexpr decltype(auto) operator ()(B& base, R value) const
{
return (base.*M) = std::move(value);
}
};
// Bind a template argument (any compatible constant) to a type (callable, convertible)
template <auto V>
constexpr const_value<V> const_v{};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment