[typeof] support for template nested types

We have recently been working to implement support for deduction of stl iterators in the typeof emulation. In the process, a method to completely deduce the type of nested templates emerged. Initially we want to make this method available in order to deduce dinkumware iterators, as there is no (standard) way to do that at present. With the method we are able to deduce e.g. std::set<UserType,user_predicate<UserType>,user_allocator<UserType>
::const_iterator, given separate registration of the template user_predicate and user_allocator.
It is possible to envision a general utility for registering template nested classes with the typeof emulation. Is there any interest in this? Otherwise we'll only add specialized code for stl iterators. The method consists of two steps. The first of which is well known. Given a type T (presumably an iterator) Lets assume it is of type std::set<T,std::greater<T> >::iterator 1. Check if it has a value_type typedef, using enable_if. 2. If it has a value_type typedef, pass the value_type to a predicate resolver (enabled with enable_if IFF the resulting iterator generated using that predicate matches T). 3. The predicate resolver sends the value_type on to the allocator resolver which uses enable_if in the same way. The allocator resolver in turn tries to match against an actual iterator, using the given value_type, predicate and allocator. Below is a sample code: deduction of allocator type is ignored for simplicity. template<class T> static char has_value_type_helper(typename T::value_type*); template<class T> static char (&has_value_type_helper(...))[2]; template<class T> struct has_value_type : boost::mpl::bool_<sizeof(has_value_type_helper<T>(0)) == sizeof(char)> {}; template<typename T,typename ValueType,typename Pred,typename Enable=void> struct deduce_set : boost::mpl::false_ {}; template<typename T,typename ValueType,typename Enable=void> struct deduce_set_predicate : boost::mpl::false_ {}; template<typename T,typename Enable=void> struct is_set_iterator : boost::mpl::false_ {}; template<typename T,typename ValueType,typename Pred> struct deduce_set<T,ValueType,Pred,typename boost::enable_if<boost::is_same<T,typename std::set<ValueType,Pred>::iterator> >::type> : boost::mpl::true_ { typedef std::set<ValueType,Pred> container_type; BOOST_STATIC_CONSTANT(bool,is_const_iterator=false); }; template<typename T,typename ValueType,typename Pred> struct deduce_set<T,ValueType,Pred,typename boost::enable_if<boost::is_same<T,typename std::set<ValueType,Pred>::const_iterator> >::type> : boost::mpl::true_ { typedef std::set<ValueType,Pred> container_type; BOOST_STATIC_CONSTANT(bool,is_const_iterator=true); }; /*Enable this template only if std::set<ValueType,std::less<ValueType>
::(const_)iterator is the same type as T */
template<typename T,typename ValueType> struct deduce_set_predicate<T,ValueType,typename boost::enable_if<deduce_set<T,ValueType,std::less<ValueType> >
::type> : deduce_set<T,ValueType,std::less<ValueType> > {};
/*Enable this template only if std::set<ValueType,std::greater<ValueType> >::(const_)iterator is the same type as T */ template<typename T,typename ValueType> struct deduce_set_predicate<T,ValueType,typename boost::enable_if<deduce_set<T,ValueType,std::greater<ValueType> >
::type> : deduce_set<T,ValueType,std::greater<ValueType> > {};
//Check if type has value_type typedef template<typename T> struct is_set_iterator<T,typename boost::enable_if<has_value_type<T> >::type > : deduce_set_predicate<T,typename T::value_type> {}; int main() { bool value=is_set_iterator<std::set<int, std::greater<int>
::iterator>::value; typedef is_set_iterator<std::set<int, std::greater<int> ::iterator>::container_type container_type; typedef is_set_iterator<int>::container_type container_type; //Fails to compile return 0; }
Regards, Peder

"Peder Holt" <peder.holt@gmail.com> wrote
We have recently been working to implement support for deduction of stl iterators in the typeof emulation. In the process, a method to completely deduce the type of nested templates emerged.
Initially we want to make this method available in order to deduce dinkumware iterators, as there is no (standard) way to do that at present. With the method we are able to deduce e.g. std::set<UserType,user_predicate<UserType>,user_allocator<UserType>
::const_iterator, given separate registration of the template user_predicate and user_allocator.
It is possible to envision a general utility for registering template nested classes with the typeof emulation. Is there any interest in this? Otherwise we'll only add specialized code for stl iterators.
Also is there any interest in a typeof-independent facility to parse an STL iterator, something like: is_iterator<It>::value; is_const<It>::value; deduce_container<It>::type; ? Regards, Arkadiy

Arkadiy Vertleyb wrote:
Also is there any interest in a typeof-independent facility to parse an STL iterator, something like:
is_iterator<It>::value; is_const<It>::value; deduce_container<It>::type;
Cool! template<class It> inline typename deduce_container<It>::type::const_iterator to_const(It it) { return it; } -- Alexander Nasonov Project Manager at Akmosoft ( http://www.akmosoft.com ) Blog: http://nasonov.blogspot.com Email: $(FirstName) dot $(LastName) at gmail dot com
participants (3)
-
Alexander Nasonov
-
Arkadiy Vertleyb
-
Peder Holt