
, // sort by less<string> on strId boost::multi_index::ordered_non_unique < boost::multi_index::tag< RsOrderIndex::ord_id >, BOOST_MULTI_INDEX_MEMBER( ord_record_item, std::string, strId ) , // sort by less<string> on strDescription boost::multi_index::ordered_non_unique < boost::multi_index::tag< RsOrderIndex::ord_desc >, BOOST_MULTI_INDEX_MEMBER( ord_record_item, std::string, strDescription ) , // sort by less<COleDateTime> on dtInService boost::multi_index::ordered_non_unique < boost::multi_index::tag< RsOrderIndex::ord_sevice >, BOOST_MULTI_INDEX_MEMBER( ord_record_item, COleDateTime,
I have a muti_index for a database. First I'll say, this will be so much better than my old way of running an SQL every time I wanted to change the order. Thanks. I never see a database bigger than some 1200 records, usually <200, so I'm not worried about memory bloat. So I've wrapped the multi_index in a class that will hide the boost includes from the rest of my app. I'll include the work below. I'd like to treat some kind of interface, like a generic iterator, depending on what order I have set. I would only use one iterator at a time. But the iterators are templated and have no base so that I can easily keep a set of iterators handy, say in a container, and then supply the appropriate iterator through an interface. In my class, RaOrderRecords, I'd something like: set.GetIt( ) set.IncIt( ) set.IsEndIt( ) etc. Or even overload so I could set++ And a member like SetOrder( [enum of new order] ) to have the internal iterator switched. I'm sure there is an elegant way to deal with this, but it escapes me. Thanks, Dan. ~~~~~ .hpp #pragma once // // ............................................................ namespace RsOrderIndex { struct ord_key{ }; struct ord_id{ }; struct ord_desc{ }; struct ord_sevice{ }; struct ord_remain{ }; struct ord_cat{ }; struct ord_group{ }; enum RecOrderIndex { ordNull, ordKey, ordId, ordDesc, ordService, ordRemain, ordCat, ordGroup, }; }; // ............................................................ class RaOrderRecords; struct ord_record_item { //properties RaOrderRecords* pParent; size_t absPos; //indexed properties long key; std::string strId; std::string strDescription; COleDateTime dtInService; long remaining; long catKey; long groupKey; //one and only constructor ord_record_item( RaOrderRecords *pInParent, long inKey, CString& inId, CString& inDesc, COleDateTime& indtIns, long inRemain, long inCatKey, long inGroupKey, size_t inPos ) :pParent( pInParent ) ,key( inKey ) ,strId( inId ) ,strDescription( inDesc ) ,dtInService( indtIns ) ,remaining( inRemain ) ,catKey( inCatKey ) ,groupKey( inGroupKey ) ,absPos( inPos ) { } //useful members size_t GetAbsPos( ) const { return absPos; } //indexing members bool operator < ( const ord_record_item& e ) const { return key < e.key; } unsigned long cat_pos( ) const; unsigned long group_pos( ) const; }; // ............................................................ #ifdef INCLUDE_ORDRECORD_BASE //to isolate boost headers typedef boost::multi_index::multi_index_container < ord_record_item, boost::multi_index::indexed_by < // sort by primary database key, ord_record_item comp boost::multi_index::ordered_unique < boost::multi_index::tag< RsOrderIndex::ord_key >, boost::multi_index::identity< ord_record_item > dtInService )
, // sort by less<COleDateTime> on remaining, Description boost::multi_index::ordered_non_unique < boost::multi_index::tag< RsOrderIndex::ord_remain >, boost::multi_index::composite_key < ord_record_item, BOOST_MULTI_INDEX_MEMBER( ord_record_item, long, remaining ), BOOST_MULTI_INDEX_MEMBER( ord_record_item, std::string, strDescription )
, // sort by category, description boost::multi_index::ordered_non_unique < boost::multi_index::tag< RsOrderIndex::ord_cat >, boost::multi_index::composite_key < ord_record_item, BOOST_MULTI_INDEX_CONST_MEM_FUN( ord_record_item, unsigned long, cat_pos ), BOOST_MULTI_INDEX_MEMBER( ord_record_item, std::string, strDescription )
, // sort by group, description boost::multi_index::ordered_non_unique < boost::multi_index::tag< RsOrderIndex::ord_group >, boost::multi_index::composite_key < ord_record_item, BOOST_MULTI_INDEX_CONST_MEM_FUN( ord_record_item, unsigned long, group_pos ), BOOST_MULTI_INDEX_MEMBER( ord_record_item, std::string, strDescription )
ord_record_set;
typedef ord_record_set::index< RsOrderIndex::ord_key >::type::iterator It_key_ord; typedef ord_record_set::index< RsOrderIndex::ord_id >::type::iterator It_id_ord; typedef ord_record_set::index< RsOrderIndex::ord_desc >::type::iterator It_desc_ord; typedef ord_record_set::index< RsOrderIndex::ord_sevice
::type::iterator It_service_ord; typedef ord_record_set::index< RsOrderIndex::ord_remain ::type::iterator It_remain_ord; typedef ord_record_set::index< RsOrderIndex::ord_cat >::type::iterator It_cat_ord; typedef ord_record_set::index< RsOrderIndex::ord_group >::type::iterator It_group_ord;
nth_index_iterator
#else // INCLUDE_ORDRECORD_BASE
//forward declared for general use, no multi record boost headers
class ord_record_set;
#endif // INCLUDE_ORDRECORD_BASE
// ............................................................
class RaOrderRecords
{
ord_record_set* pOrder;
RaCatGroupMap catSet;
RaCatGroupMap groupSet;
//RSKeyPosSet keyPosSet;
public:
RaOrderRecords( );
~RaOrderRecords( );
bool ReadRecordSet( RaRecordset* pRS );
unsigned long GetCatPos( long inCatKey )
{
RaCatGroupMapIt it= catSet.find( inCatKey );
if( it != catSet.end( ) )
return it->second.ordered;
else
return -1;//max unsigned
}
unsigned long GetGroupPos( long inGroupKey )
{
RaCatGroupMapIt it= groupSet.find( inGroupKey );
if( it != groupSet.end( ) )
return it->second.ordered;
else
return -1;//max unsigned
}
#ifdef _DEBUG
void Dump( RsOrderIndex::RecOrderIndex index );
#else
void Dump( RsOrderIndex::RecOrderIndex index ) { }
#endif
};
~~~~~~.cpp
#include "stdafx.h"
#if !defined(NDEBUG)
#include

Dan Bloomquist
I have a muti_index for a database. First I'll say, this will be so much better than my old way of running an SQL every time I wanted to change the order. Thanks. I never see a database bigger than some 1200 records, usually <200, so I'm not worried about memory bloat.
So I've wrapped the multi_index in a class that will hide the boost includes from the rest of my app. I'll include the work below. I'd like to treat some kind of interface, like a generic iterator, depending on what order I have set. I would only use one iterator at a time. But the iterators are templated and have no base so that I can easily keep a set of iterators handy, say in a container, and then supply the appropriate iterator through an interface.
Not sure whether this is what you'r after, but have you considered using adobe::any_iterator? http://stlab.adobe.com/classadobe_1_1any__iterator.html adobe::any_iterator is a polymorphic iterator wrapper so that you can use it to handle at run-time any iterator with the specified category (bidirectional, foward, etc.) Kind of like boost::any for general objects, but already specialized for the iterator interface. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

Joaquin M Lopez Munoz wrote:
Dan Bloomquist
writes: Not sure whether this is what you'r after, but have you considered using adobe::any_iterator?
http://stlab.adobe.com/classadobe_1_1any__iterator.html
adobe::any_iterator is a polymorphic iterator wrapper so that you can use it to handle at run-time any iterator with the specified category (bidirectional, foward, etc.) Kind of like boost::any for general objects, but already specialized for the iterator interface.
Hi Joaquin,
Thank you for the link. I'm on tangents right now but have/will look
over these adobe headers. I have attempted to write my own based on
itereator_facade. I've gotten all the members to work except for
dereferance. I've looked every example I can find where it works, but in
my case some iterator base gets called which is invalid. I've even tried
overriding the arrow operator. In that case I land in operators.hhp with:
template
{ friend class boost::iterator_core_access; friend RaOrderRecords; //container RaOrderRecords* pParent; //this index RsOrderIndex::RecOrderIndex index; //iterators for proxy SP_it_adaptor_container spIterators; public: //base( ) const { return *this; } RaOrderRecordsIt( RaOrderRecords* pPrnt, RsOrderIndex::RecOrderIndex inIdx ); RaOrderRecordsIt( ) :pParent( NULL )//for asserts { } void increment( );// { } bool equal( const RaOrderRecordsIt& f2 ) const; ord_record_item const& dereference( ) const; //ord_record_item& dereference( ) const; const ord_record_item* operator->( ) const; RaOrderRecordsIt begin( ); RaOrderRecordsIt end( ); };

Dan Bloomquist
Joaquin M Lopez Munoz wrote:
Dan Bloomquist
writes: Not sure whether this is what you'r after, but have you considered using adobe::any_iterator?
http://stlab.adobe.com/classadobe_1_1any__iterator.html
adobe::any_iterator is a polymorphic iterator wrapper so that you can use it to handle at run-time any iterator with the specified category (bidirectional, foward, etc.) Kind of like boost::any for general objects, but already specialized for the iterator interface.
Hi Joaquin, Thank you for the link. I'm on tangents right now but have/will look over these adobe headers. I have attempted to write my own based on itereator_facade. I've gotten all the members to work except for dereferance [...]
I suggest you take a deep look at adobe::any_iterator for inspiration or, better yet, use it directly (it's an all header library, and the licensing terms are very convenient.) I suspect using boost::iterator_facade is not the way to go here: for one, all your iterator wrapper operations (increment, dereference, etc.) have to be built in terms of a virtual interface , which iterator_facade does not lends itself to. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

Joaquin M Lopez Munoz wrote:
Dan Bloomquist
writes: Joaquin M Lopez Munoz wrote:
Dan Bloomquist
writes: Not sure whether this is what you'r after, but have you considered using adobe::any_iterator?
http://stlab.adobe.com/classadobe_1_1any__iterator.html
adobe::any_iterator is a polymorphic iterator wrapper so that you can use it to handle at run-time any iterator with the specified category (bidirectional, foward, etc.) Kind of like boost::any for general objects, but already specialized for the iterator interface.
Hi Joaquin, Thank you for the link. I'm on tangents right now but have/will look over these adobe headers. I have attempted to write my own based on itereator_facade. I've gotten all the members to work except for dereferance [...]
I suggest you take a deep look at adobe::any_iterator for inspiration or, better yet, use it directly (it's an all header library, and the licensing terms are very convenient.) I suspect using boost::iterator_facade is not the way to go here: for one, all your iterator wrapper operations (increment, dereference, etc.) have to be built in terms of a virtual interface , which iterator_facade does not lends itself to.
Hi Jaoquin, Thanks. I found the poly download actually it is there asl_1.0.42. A lot more stuff than the header I first looked at. http://stlab.adobe.com/iterator_8hpp_source.html Most of that was built on iterator_facade. It will take me some time but I'll see what I can do with it. This is as much to learn as to use it in my app. Best, Dan.

Hi,
I suggest you take a deep look at adobe::any_iterator for inspiration or, better yet, use it directly (it's an all header library, and the licensing terms are very convenient.) I suspect using boost::iterator_facade is not the way to go here: for one, all your iterator wrapper operations (increment, dereference, etc.) have to be built in terms of a virtual interface , which iterator_facade does not lends itself to.
Are you referring to some older version of any_iterator? The recent version I got from SF does not in fact contain adobe::any_iterator (the docs were not updated, it seems), but rather adobe::iter and adobe::bidirectional_iter - but I was not able to use these with B.MI so far. From the changelog it seems they changed the internals to use "the poly<> concept", whatever this means, and I guess this is when any_iterator disappeared... Thanks, Filip

Filip Konvička escribió:
Hi,
I suggest you take a deep look at adobe::any_iterator for inspiration or, better yet, use it directly (it's an all header library, and the licensing terms are very convenient.) I suspect using boost::iterator_facade is not the way to go here: for one, all your iterator wrapper operations (increment, dereference, etc.) have to be built in terms of a virtual interface , which iterator_facade does not lends itself to.
Are you referring to some older version of any_iterator? The recent version I got from SF does not in fact contain adobe::any_iterator (the docs were not updated, it seems), but rather adobe::iter and adobe::bidirectional_iter - but I was not able to use these with B.MI so far.
Yes, you are right, they changed this bit of their library. When you say
wou weren't able, do you
mean that you haven't had the chance yet or that you had problems? In
principle,
adobe::any_iterator

Yes, you are right, they changed this bit of their library. When you say wou weren't able, do you mean that you haven't had the chance yet or that you had problems? In principle,
adobe::any_iterator
is the same as
adobe::bidirectional_iter<T>
so the migration to the new interface should be straightforward.
I'm using MSVC 2010 for the experiment, if that matters... Using
adobe::bidirectional_iter gives me
adobe\any_iterator.hpp(154): error C2675: unary '--' :
'boost::multi_index::detail::hashed_index_iterator

Filip Konvička
adobe::any_iterator
is the same as
adobe::bidirectional_iter<T>
so the migration to the new interface should be straightforward.
I'm using MSVC 2010 for the experiment, if that matters... Using adobe::bidirectional_iter gives me
adobe\any_iterator.hpp(154): error C2675: unary '--' : 'boost::multi_index::detail::hashed_index_iterator
' does not define this operator or a conversion to a type acceptable to the predefined operator
Expected, since hashed index iterators are not bidirectional, only forward.
Using adobe::iter gives me:
adobe\any_iterator.hpp(63): error C2039: 'interface_ref' : is not a member of 'adobe::poly_iterator_instance
::type<I>'
I think this is a bug with adobe::iter. I've filed a bug report at http://tinyurl.com/2ubs9z2 . Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

adobe\any_iterator.hpp(154): error C2675: unary '--' : 'boost::multi_index::detail::hashed_index_iterator
' does not define this operator or a conversion to a type acceptable to the predefined operator Expected, since hashed index iterators are not bidirectional, only forward.
Yes, that's what I thought, so I tried adobe::iter.
Using adobe::iter gives me:
adobe\any_iterator.hpp(63): error C2039: 'interface_ref' : is not a member of 'adobe::poly_iterator_instance
::type<I>' I think this is a bug with adobe::iter. I've filed a bug report at http://tinyurl.com/2ubs9z2 .
Thank you! Your patch works for me. My motivation in exploring this is that most of template instantiations in my code seems to be related to B.MI. I found out by using the (very iteresting) template profiler of Steven Watanabe. I might be just mis-interpreting the results...but I thought I would move most of the containers out of the headers. Thanks again, Filip
participants (4)
-
Dan Bloomquist
-
Filip Konvička
-
Joaquin M Lopez Munoz
-
joaquin@tid.es