
, // 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