Created
September 20, 2018 14:09
-
-
Save Nekotekina/cc913bbd2386c593fe4beb3da9d1b3db to your computer and use it in GitHub Desktop.
const_v<> template variable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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