[Multi-Index] has_index<BMI,TAG> meta-function

I'd like to use enable_if/disable_if with a meta-function that determines whether a given multi-index container has a given tagged index. But I'm not having success writing has_index<BMI,TAG>, even looking at BMI's own index<Tag> meta-function :( Does anyone know how to implement it? Below how I'd like to use it. Thanks, --DD struct ByName {}; template <class BMI> struct VCursor { virtual void filter_by_name(const string& name) { do_filter_by_name(name); } private: void do_filter_by_name( const string& name, typename boost::enable_if<has_index<BMI, ByName> >::type* /*dummy*/ = 0 ) { typedef typename BMI::template index<ByName>::type index_type; ... } void do_filter_by_name( const string& name, typename boost::disable_if<has_index<BMI, ByName> >::type* /*dummy*/ = 0 ) { throw "no name index"; } };

________________________________________ De: boost-users-bounces@lists.boost.org [boost-users-bounces@lists.boost.org] En nombre de Dominique Devienne [ddevienne@gmail.com] Enviado el: martes, 14 de julio de 2009 23:18 Para: boost-users Asunto: [Boost-users] [Multi-Index] has_index<BMI,TAG> meta-function
You can use this: template<typename Index> struct tag_list { typedef typename Index::tag_list type; }; template<typename MultiIndexContainer,typename Tag> struct has_index: boost::mpl::contains< boost::mpl::transform_view< typename MultiIndexContainer::index_type_list, boost::mpl::contains<tag_list<boost::mpl::_>,Tag> >, boost::mpl::true_
{}; which BTW relies on the mistakenly undocumented nested type tag_list that all indices are equipped with. I'll update the docs when I find some time. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

On Tue, Jul 14, 2009 at 5:11 PM, JOAQUIN M. LOPEZ MUÑOZ<joaquin@tid.es> wrote:
Thanks. This appears to be working for me (i.e. I'm getting to errors past this code, which I'll need to clear before I can fully test it). My own attempt below fails on tag_list precisely, and I don't understand why. Your post came just in time :) Although if someone can point where mine went wrong, I'm still interested. Once again, thank you Joaquín! --DD error C2039: 'tag_list' : is not a member of 'boost::mpl::vector3<T0,T1,T2>' boost\multi_index\detail\has_tag.hpp 31 error C2146: syntax error : missing ',' before identifier 'tag_list' boost\multi_index\detail\has_tag.hpp 31 error C2065: 'tag_list' : undeclared identifier boost\multi_index\detail\has_tag.hpp 31 error C2955: 'boost::mpl::contains' : use of class template requires template argument list boost\multi_index\detail\has_tag.hpp 32 using namespace boost; using boost::multi_index::detail::has_tag; template<typename BMI, typename TAG> struct has_index { typedef typename BMI::index_type_list index_type_list; typedef typename mpl::end<index_type_list>::type index_type_list_end; typedef typename has_tag<TAG>::template apply<index_type_list>::type iter; BOOST_STATIC_CONSTANT(bool, value =!(is_same<iter, index_type_list_end>::value)); };

________________________________________ De: boost-users-bounces@lists.boost.org [boost-users-bounces@lists.boost.org] En nombre de Dominique Devienne [ddevienne@gmail.com] Enviado el: miércoles, 15 de julio de 2009 0:37 Para: boost-users@lists.boost.org Asunto: Re: [Boost-users] [Multi-Index] has_index<BMI,TAG> meta-function On Tue, Jul 14, 2009 at 5:11 PM, JOAQUIN M. LOPEZ MUÑOZ<joaquin@tid.es> wrote:
has_tag applies to each index individually, not the entire index_type_list. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

On Tue, Jul 14, 2009 at 5:49 PM, JOAQUIN M. LOPEZ MUÑOZ<joaquin@tid.es> wrote:
I see it now. Thanks for pointing it out. One last question tonight :) Similarly to how I can now statically enable/disable code based on which index is implemented by a BMI, can one also change that code based on whether the index is unique vs non-unique? Or ordered vs hashed? For example, using D's static if, could I do static if (index.is_unique) { // using index.find } else { // using index.equal_range } Thanks, --DD

Dominique Devienne <ddevienne <at> gmail.com> writes:
On Tue, Jul 14, 2009 at 5:49 PM, JOAQUIN M. LOPEZ MUÑOZ<joaquin <at> tid.es>
One last question tonight :)
Sorry it's been a little later than that. I've been offline for the last couple of days.
Use index_specifier_type_list instead of index_type_list (differences explained at http://tinyurl.com/nwe27r ) and resort to something like this: template<typename IndexSpecifier> struct is_unique_index:boost::mpl::false_{}; template<typename TagList,typename KeyFromValue,typename Compare> struct is_unique_index< boost::multi_index::ordered_unique<TagList,KeyFromValue,Compare>
:boost::mpl::true_{};
template<typename TagList,typename KeyFromValue,typename Hash,typename Pred> struct is_unique_index< boost::multi_index::hashed_unique<TagList,KeyFromValue,Hash,Pred>
:boost::mpl::true_{};
and similarly for ordered vs hashed. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

On Fri, Jul 17, 2009 at 9:07 AM, Joaquin M Lopez Munoz<joaquin@tid.es> wrote:
Thanks. Partial specialization I understand at least :) Although that's the first time I see the specialization having more template arguments than the base template, and that threw me off initially, but I see there's still a single template argument in is_unique_index, which happens to be a template itself. Thanks a bunch. --DD
participants (3)
-
Dominique Devienne
-
Joaquin M Lopez Munoz
-
JOAQUIN M. LOPEZ MUÑOZ