Imagine I want to make a tuple like template container as part of api interface. And I want to constraint it to the list of allowed types plus an instance of this template container. Now I have something like this:
#include <string>
#include <tuple>
#include <utility>
#include <type_traits>
template<typename T>
constexpr const bool bIsAllowedType =
std::is_same<T, bool>::value ||
std::is_same<T, void*>::value ||
std::is_same<T, double>::value ||
std::is_same<T, int64_t>::value ||
std::is_same<T, std::string>::value;
template<typename T, typename... Args>
constexpr const bool bIsAllowedArgList =
bIsAllowedType<std::remove_reference_t<T>> &&
bIsAllowedArgList<Args...>;
template<typename T>
constexpr const bool bIsAllowedArgList<T> =
bIsAllowedType<std::remove_reference_t<T>>;
template<typename... Args>
concept CAllowedArgList =
bIsAllowedArgList<Args...>;
template<CAllowedArgList... Args>
class Container
{
private:
using TupleT = std::tuple<std::decay_t<Args>...>;
TupleT data;
public:
Container() = default;
Container(Args&&... args) : data(std::forward<Args>(args)...) {}
};
int main()
{
auto test_cont = Container(1LL, 2.0, std::string("three")); // Ok
auto err_cont = Container(std::wstring(L"wide string")); // Not ok, type's not allowed
return 0;
}
So, how do I make it to also accept an instance of itself? Like this:
int main()
{
auto test_cont = Container(1LL, Container(2.0, std::string("three")));
return 0;
}
I want it to be as simple as possible, so please restraint using third party libs (like Boost) if possible