[tuple] any interest in a unique_tuple<...>?
Testing the water, see if anyone might find this useful. Any comments/suggestions are absolutely welcome and appreciated! unique_tuple<T...>, where types in <T...> may themselves be other unqiue_tupe<...>'s, contains exactly one copy of each of the "finally nested" element types in <T...>, regardless of how many times a type appears in the type parameter pack, or how deeply it is nested inside one or more unique_tuple's in <T...>. unique_tuple<T...> differs from std::tuple<T...> and boost::fusion::set<T...> etc in that nested unique_tuple's are effectively "flattened", and elements contained are unique no matter how complex the nesting gets, or how many times or how deeply nested the element type is in <T...>. unique_tuple<T...> in a way emulates virtual inheritance, but at compile time. The implementation does NOT use virtual inheritance. implementation is available at: https://www.dropbox.com/sh/f7ur7j6jetabovj/MuhhhNWU0K/unique_tuple.h and some demonstration of uses at (tested with "clang-3.5 -std=c++1y" on mac osx/macport) https://www.dropbox.com/sh/f7ur7j6jetabovj/cy_cvpPIYc/main.cpp In the following example, t1,t2,t3 all contain exactly one A, and exactly one B: struct A{}; struct B{}; unique_tuple<A,B,A,B> t1(A{},B{}); unique_tuple<A,unique_tuple<B>,unique_tuple<A,B>> t2{B{},A{}}; // order doesn't matter in constructor // B is default constructed, empty unique_tuple (possibly nested) doesn't matter unique_tuple<A,unique_tuple<unique_tuple<>>,unique_tuple<A,B,unique_tuple<A,B,unique_tuple<A,B>>>> t3{A{}}; // unique_tuple<A,B> t4(A{},B{},A{}); // doesn't compile because more than one A is supplied // unique_tuple<A,B> t5(A{},B{},1.0); // doesn't compile because double doesn't belong There are helper classes and functions, e.g.: A& a = get<A>(t0); auto x = make_unique_tuple(A{},B{},1,1.0); // unique_tuple<A,B,int,double> static_assert( is_unique_tuple<decltype(t0)>::value, "t0 is a unique_tuple type" ); static_assert( is_element_of<A,decltype(t1)>::value, "A is an element in t1" ); static_assert( is_subset_of<decltype(t1),decltype(x)>::value, "<A,B> is a subset of <A,B,int,double>" ); static_assert( unique_tuple_size<decltype(t3)>::value == 2, "there are 2 elements in t3: A and B" ); Equality comparason exists for two unique_tuple<...>s that contain the same element types, e.g., t0 == t2 && t1 != t3; Mixed operations with std::tuple are available if std::get<typename>(std::tuple<...>) exists (c++14), which effectively requires that the element types are all unique in the std::tuple<...>. synopsis: template < typename... T > struct unique_tuple { template < typename... U > explicit constexpr unique_tuple(U&&...); template < typename... U > explicit constexpr unique_tuple(const std::tuple<U...>&); template < typename... U > explicit constexpr unique_tuple(std::tuple<U...>&&); // allocator extended constructors template < typename Alloc, typename... U > unique_tuple(std::allocator_arg_t, const Alloc& a, U&&...); template < typename Alloc, typename... U > unique_tuple(std::allocator_arg_t, const Alloc& a, const unique_tuple<U...>&); template < typename Alloc, typename... U > unique_tuple(std::allocator_arg_t, const Alloc& a, unique_tuple<U...>&&); template < typename Alloc, typename... U > unique_tuple(std::allocator_arg_t, const Alloc& a, const std::tuple<U...>&); template < typename Alloc, typename... U > unique_tuple(std::allocator_arg_t, const Alloc& a, std::tuple<U...>&&); // assign template < typename... U > unique_tuple& operator=(const unique_tuple<U...>&); template < typename... U > unique_tuple& operator=(unique_tuple<U...>&&); template < typename... U > unique_tuple& operator=(const std::tuple<U...>&); template < typename... U > unique_tuple& operator=(std::tuple<U...>&&); // swap template < typename... U > void swap(unique_tuple<U...>&); template < typename... U > void swap(std::tuple<U...>&); }; // helpers template < typename... T > unique_tuple<typename std::decay<T>::type...> make_unique_tuple(T&&... t); template < typename... T > struct unique_tuple_size<unique_tuple<T...>>; // number of unique elements template < typename T > struct is_unique_tuple; template < typename T, typename... U > struct is_element_of<T,unique_tuple<U...>>; template < typename... T, typename... U > struct is_subset_of<unique_tuple<T...>,unique_tuple<U...>>; // element access template < typename T, typename... U > T& get<T>(unique_tuple<U...>&); template < typename T, typename... U > const T& get<T>(const unique_tuple<U...>&); template < typename T, typename... U > T&& get<T>(unique_tuple<U...>&&); // equality compare template < typename... T, typename... U > bool operator==(const unique_tuple<T...>&, const unique_tuple<U...>&); template < typename... T, typename... U > bool operator==(const unique_tuple<T...>&, const std::tuple<U...>&); template < typename... T, typename... U > bool operator==(const std::tuple<T...>&, const unique_tuple<U...>&); template < typename... T, typename... U > bool operator!=(const unique_tuple<T...>&, const unique_tuple<U...>&); template < typename... T, typename... U > bool operator!=(const unique_tuple<T...>&, const std::tuple<U...>&); template < typename... T, typename... U > bool operator!=(const std::tuple<T...>&, const unique_tuple<U...>&); // swap template < typename... T, typename... U > void swap(unique_tuple<T...>&, unique_tuple<U...>&); template < typename... T, typename... U > void swap(unique_tuple<T...>&, std::tuple<U...>&); template < typename... T, typename... U > void swap(std::tuple<T...>&, unique_tuple<U...>&);
AMDG On 03/08/2014 09:24 AM, Hui Li wrote:
Testing the water, see if anyone might find this useful. Any comments/suggestions are absolutely welcome and appreciated!
The behavior of this seems a bit odd to me. If I needed something like this, I think I would prefer to create a normal tuple or fusion::set in conjunction some form of set_union algorithm.
unique_tuple<T...>, where types in <T...> may themselves be other unqiue_tupe<...>'s, contains exactly one copy of each of the "finally nested" element types in <T...>, regardless of how many times a type appears in the type parameter pack, or how deeply it is nested inside one or more unique_tuple's in <T...>.
unique_tuple<T...> differs from std::tuple<T...> and boost::fusion::set<T...> etc in that nested unique_tuple's are effectively "flattened", and elements contained are unique no matter how complex the nesting gets, or how many times or how deeply nested the element type is in <T...>.
In Christ, Steven Watanabe
On Mar 8, 2014, at 12:41 PM, Steven Watanabe <watanabesj@gmail.com> wrote:
AMDG
On 03/08/2014 09:24 AM, Hui Li wrote:
Testing the water, see if anyone might find this useful. Any comments/suggestions are absolutely welcome and appreciated!
The behavior of this seems a bit odd to me. If I needed something like this, I think I would prefer to create a normal tuple or fusion::set in conjunction some form of set_union algorithm.
That certainly would achieve similar functionality. But I do find that simply putting two "set"s inside another "set" to achieve "set union" is convenient. Also the fact that std::tuple and fusion::set care about the order in which the element types are specified can cause trouble, or at least make certain things hard (sometimes may not even be possible), i.e., when it comes to constructors, element-wise comparison and swap etc.
unique_tuple<T...>, where types in <T...> may themselves be other unqiue_tupe<...>'s, contains exactly one copy of each of the "finally nested" element types in <T...>, regardless of how many times a type appears in the type parameter pack, or how deeply it is nested inside one or more unique_tuple's in <T...>.
unique_tuple<T...> differs from std::tuple<T...> and boost::fusion::set<T...> etc in that nested unique_tuple's are effectively "flattened", and elements contained are unique no matter how complex the nesting gets, or how many times or how deeply nested the element type is in <T...>.
In Christ, Steven Watanabe
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (2)
-
Hui Li
-
Steven Watanabe