Я решил опубликовать собственное решение, которое в итоге использовал для потомков, и в случае, если кому-то будет любопытно или есть какие-либо комментарии. Пожалуйста, простите за жесткое форматирование; Это было избавление от горизонтального свитка.
Дайте мне знать в разделе комментариев, если вы используете это. Мне было бы любопытно услышать, было ли это полезно кому-то еще.
Нам понадобятся следующие заголовки:
#include <boost/range/iterator_range.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/shared_array.hpp>
#include <vector>
Помощник для привязки к существующему пересчитанному объекту
template<typename RefCountedTypeT>
struct RefCountLinkFunctor
{
public:
RefCountLinkFunctor( const RefCountedTypeT & ptr )
: m_ptr(ptr)
{
&RefCountedTypeT::use_count; // try to check if refcounted
}
template<typename T> void operator()(T*) {}
protected:
RefCountedTypeT m_ptr;
};
А потом:
template< typename DataT >
class DataRange : public boost::iterator_range< DataT * >
{
public:
typedef boost::iterator_range< DataT * > ParentType;
typedef DataRange< DataT > OwnType;
typedef DataT DataType;
typedef boost::iterator_range< DataType * > Range;
typedef boost::shared_ptr< OwnType > Ptr;
typedef std::vector<DataType> DataVector;
typedef boost::shared_ptr<DataVector> DataVectorPtr;
static Ptr allocateShared( std::size_t size )
{
typedef boost::shared_array<DataType> DataSharedArray;
typedef RefCountLinkFunctor<DataSharedArray> Deleter;
DataSharedArray dataArray( new DataType[size] );
Deleter deleter( dataArray );
DataT * begin = dataArray.get();
DataT * end = begin + size;
return Ptr( new OwnType(begin, end), deleter);
}
template< typename RefCountedT >
static Ptr
makeShared( DataType * begin, DataType * end, const RefCountedT & refObj )
{
RefCountLinkFunctor< RefCountedT > deleter( refObj );
return Ptr( new OwnType(begin, end), deleter );
}
template< typename RefCountedT, typename InDataT >
static Ptr
makeShared( DataVector & data, const RefCountedT & refObj )
{
RefCountLinkFunctor< RefCountedT > deleter( refObj );
DataType * begin = &data.front();
DataType * end = begin + data.size();
return makeShared( begin, end, deleter );
}
static Ptr makeShared( const DataVectorPtr & data )
{
typedef boost::shared_ptr< std::vector<DataType> > InputVectorPtr;
RefCountLinkFunctor< InputVectorPtr > deleter( data );
DataType * begin = &data->front();
DataType * end = begin + data->size();
return makeShared( begin, end, deleter );
}
protected:
DataRange( DataType * begin, DataType * end ) : ParentType( begin, end ){}
};