Simplified tuple implementation

I am working on a platform that does not contain any standard libraries, and I'm trying to implement a "tuple-like type".

I only need the means to enter the type, but I would like the compiler to enter static_assert if the type does not exist. There is no need to argue on duplicate types, but it would be nice ...

Here is what I tried:

 template<class... Args> struct SimpleTuple; template<> struct SimpleTuple<> { SimpleTuple() { } }; template<class Head, class... Tail> struct SimpleTuple<Head, Tail...> { typedef Head HeadType; typedef SimpleTuple<Tail...> VATailType; SimpleTuple(Head head, Tail... tail) : data(head), rest(tail...) { } // Does not compile, because explicit specialization in non-namespace // scope is not allowed template<typename T> T& get() { return rest.get<T>(); } template<> Head& get() { return data; } Head data; VATailType rest; }; 

I know why it fails, but I do not know how to avoid this limitation.

I am looking somehow for a possible implementation of this.

+4
source share
1 answer

You can use SFINAE to participate in an overload of only one of two overloads, based on whether the type T is the same as Head :

 #include <type_traits> // For std::enable_if and std::is_same template<typename T, typename std::enable_if<!std::is_same<T, Head>::value>::type* = nullptr> T& get() { return rest.get<T>(); } template<typename T, typename std::enable_if<std::is_same<T, Head>::value>::type* = nullptr> Head& get() { return data; } 

Both std::enable_if and std::is_same can be easily implemented if you cannot use them from the standard library. For instance:

 template<typename T, typename U> struct is_same { static constexpr bool value = false; }; template<typename T> struct is_same<T, T> { static constexpr bool value = true; }; template<bool C, typename T = void> struct enable_if { }; template<typename T> struct enable_if<true, T> { using type = T; }; 

Here is a living example .

As for the static statement, you can define a simple attribute that checks for the presence of a given type in a given type (this attribute can also be defined in terms of std::conditional , which is also trivial to implement):

 template<typename...> struct SimpleTuple; template<typename T, typename U> struct has_type { static constexpr bool value = false; }; template<typename T, typename U, typename... Ts> struct has_type<T, SimpleTuple<U, Ts...>> { static constexpr bool value = has_type<T, SimpleTuple<Ts...>>::value; }; template<typename T, typename... Ts> struct has_type<T, SimpleTuple<T, Ts...>> { static constexpr bool value = true; }; template<typename T> struct has_type<T, SimpleTuple<>> { static constexpr bool value = false; }; 

And then use it like this:

 template<typename T, typename enable_if<!is_same<T, Head>::value>::type* = nullptr> T& get() { static_assert(has_type<T, SimpleTuple>::value, "Type not found!"); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ return rest.get<T>(); } 

Here is a live example that uses static_assert() above.

If you also want to check whether a tuple contains a certain type only once, you can use the following attribute, which is a trivial modification of the has_type attribute above:

 template<typename...> struct SimpleTuple; template<typename T, typename U> struct has_unique_type { static constexpr bool value = false; }; template<typename T, typename U, typename... Ts> struct has_unique_type<T, SimpleTuple<U, Ts...>> { static constexpr bool value = has_unique_type<T, SimpleTuple<Ts...>>::value; }; template<typename T, typename... Ts> struct has_unique_type<T, SimpleTuple<T, Ts...>> { static constexpr bool value = !has_unique_type<T, SimpleTuple<Ts...>>::value; }; template<typename T> struct has_unique_type<T, SimpleTuple<>> { static constexpr bool value = false; }; 

And use it like this:

 template<typename T, typename enable_if<!is_same<T, Head>::value>::type* = nullptr> T& get() { static_assert(has_unique_type<T, SimpleTuple>::value, "Type not found or not unique!"); return rest.get<T>(); } 

Here is a living example .

+7
source

Source: https://habr.com/ru/post/1489552/


All Articles