having an alternate function based on some trait .. exactly how to do?

A

abir

HI,
i have a class like this (simplified version)
template<typename C>
class range_view{
public: /// all of the container typedefs.
iterator begin(){
return cont_.begin()+range_.first;
}
iterator end(){
return cont_.begin()+range_.second;
}
private:
C* cont_;
std::pait<size_type,size_type> range_;
};

now i want to handle begin & end different way some container. At
present i copied it again written as,

template<typename C, typename M = C::remove_aware>
class range_view{
public: /// all of the container typedefs.
iterator begin(){
return cont_->begin()+range_.first+cont_->remove_count();
}
iterator end(){
return cont_->begin()+range_.second+cont_->remove_count();
}
private:
C* cont_;
std::pait<size_type,size_type> range_;
};
so, instead of having a full class for a remove aware container, i
want just begin & end should match with the trait...
anyways can it be done using SFINAE ?
thanks
abir
 
G

gnuyuva

HI,
i have a class like this (simplified version)
template<typename C>
class range_view{
public: /// all of the container typedefs.
iterator begin(){
return cont_.begin()+range_.first;
}
iterator end(){
return cont_.begin()+range_.second;
}
private:
C* cont_;
std::pait<size_type,size_type> range_;
};

now i want to handle begin & end different way some container. At
present i copied it again written as,

template<typename C, typename M = C::remove_aware>
class range_view{
public: /// all of the container typedefs.
iterator begin(){
return cont_->begin()+range_.first+cont_->remove_count();
}
iterator end(){
return cont_->begin()+range_.second+cont_->remove_count();
}
private:
C* cont_;
std::pait<size_type,size_type> range_;
};

First of all, the code you have written is quite confusing. There are
two definitions for range_view. I don't think that the second one is a
specialization. Apart from this: "cont_->begin() + range_.first" is
only valid for basic arrays or std::vector (if we assume that all the
values are contiguous in the memory and it is always!).
so, instead of having a full class for a remove aware container, i
want just begin & end should match with the trait...
anyways can it be done using SFINAE ?

For me (from what i have got from your code), its enough if you
specialize begin() and end() functions. Its better if you post some
more code.
 
A

abir

First of all, the code you have written is quite confusing. There are
two definitions for range_view. I don't think that the second one is a
specialization. Apart from this: "cont_->begin() + range_.first" is
only valid for basic arrays or std::vector (if we assume that all the
values are contiguous in the memory and it is always!).


For me (from what i have got from your code), its enough if you
specialize begin() and end() functions. Its better if you post some
more code.
Ok, i am giving a full so far working example (just working one ....
not complete in its description. esp the reorient_iterator class which
is nearly same as boost permutation_iterator). the range_view (or
actually the class was reorient_view) works ONLY on random access
container ... but not necessarily a contiguous memory one (including
range_view, they can work with deque or some other container also)
CODE: (little long to make it a workable code)
Here what i want is that reorient_view and its specialization should
be a single implementation, where begin & end (a few other) will be
specialized for memorable tag ... , rather than the whole class
specialization
template<typename T>
class memory_vector{
private:
typedef std::deque<T> cont_t;
struct is_memorable : public boost::true_type{};
public:
typedef typename cont_t::value_type value_type;
typedef typename cont_t::size_type size_type;
typedef typename cont_t::iterator iterator;
typedef typename cont_t::const_iterator const_iterator;
typedef typename cont_t::reverse_iterator reverse_iterator;
typedef typename cont_t::const_reverse_iterator
const_reverse_iterator;
typedef typename cont_t::reference reference;
typedef typename cont_t::const_reference const_reference;
typedef typename cont_t::pointer pointer;
typedef typename cont_t::const_pointer const_pointer;
typedef typename cont_t::difference_type difference_type;
typedef is_memorable memorable;
private:
size_type remove_count_;
cont_t cont_;
public:
memory_vector() : cont_(),remove_count_(0){}
template<typename C>
memory_vector(const C& c) : remove_count_(0){
typename C::const_iterator it = c.begin();
typename C::const_iterator end = c.end();
for(; it!= end; ++it) cont_.push_back(*it);
}
iterator begin(){ return cont_.begin(); }
iterator end(){ return cont_.end();}
reverse_iterator rbegin() { return cont_.rbegin();}
reverse_iterator rend(){ return cont_.rend();}
const_iterator begin()const{ return cont_.begin();}
const_iterator end()const{ return cont_.end();}
const_reverse_iterator rbegin()const{ return cont_.rbegin();}
const_reverse_iterator rend()const{ return cont_.rend();}
void push_back(const value_type& v){
cont_.push_back(v);
}
void pop_front(){
cont_.pop_front();
++remove_count_;
}
size_type remove_count()const{ return remove_count_;}
};
template<typename ElemIter,typename IndexIter>
class reorient_iterator : public ElemIter{
public:
typedef typename ElemIter::iterator_category iterator_category;
typedef typename ElemIter::value_type value_type;
typedef typename ElemIter::reference reference;
typedef typename ElemIter::pointer pointer;
typedef reorient_iterator<ElemIter,IndexIter> self_type;
//typedef typename T::size_type size_type;
public:
reorient_iterator(ElemIter it,IndexIter pos) : it_(it),pos_(pos){}
self_type& operator++(){
++pos_;
return *this;
}
self_type operator++(int){
self_type tmp(*this);
pos++;
return tmp;
}
self_type& operator--(){
--pos_;
return *this;
}
reference operator*(){
return *(it_+*pos_);
}
pointer operator->(){
return it_+*pos_;
}
bool operator!= (const self_type& other){
return it_+*pos_ != other.it_+ *other.pos_;
}
private:
ElemIter it_;
IndexIter pos_;
};
template<class ElemIterT, class IndexIterT>
inline reorient_iterator<ElemIterT,IndexIterT>
make_reorient_iterator(ElemIterT eit, IndexIterT iit){
typedef reorient_iterator<ElemIterT,IndexIterT> result_t;
return result_t(eit,iit);
}
template<typename C,typename Enable = void>
class reorient_view{
public:
typedef reorient_view<C,Enable> self_type;
typedef typename C::value_type value_type;
typedef typename C::size_type size_type;
typedef typename C::reference reference;
typedef typename C::pointer pointer;
typedef typename C::const_reference const_reference;
typedef typename C::const_pointer const_pointer;
typedef std::vector<size_type> index_t;
typedef reorient_iterator<typename C::iterator,
typename index_t::iterator > iterator;
typedef reorient_iterator<typename C::const_iterator,
typename index_t::iterator> const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
template<typename I>
reorient_view(C& cont,const I& index) :cont_(&cont){
typename I::const_iterator it = index.begin();
typename I::const_iterator end = index.end();
for(;it!=end; ++it){
index_.push_back(*it);
}
}
iterator begin(){
return make_reorient_iterator(cont_->begin(),index_.begin());
}
iterator end(){
return make_reorient_iterator(cont_->begin(),index_.end());
}
reverse_iterator rbegin(){
return std::reverse_iterator<iterator>(rend());
}
reverse_iterator rend(){
return std::reverse_iterator<iterator>(rbegin());
}
private:
index_t index_;
C* cont_;
};
template<typename C>
class reorient_view<C, typename boost::enable_if<typename
C::is_memorable>::type >{
public:
typedef typename C::value_type value_type;
typedef typename C::size_type size_type;
typedef typename C::reference reference;
typedef typename C::pointer pointer;
typedef typename C::const_reference const_reference;
typedef typename C::const_pointer const_pointer;
typedef std::vector<size_type> index_t;
typedef reorient_iterator<typename C::iterator,
typename index_t::iterator > iterator;
typedef reorient_iterator<typename C::const_iterator,
typename index_t::iterator> const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
public:
template<typename I>
reorient_view(C& cont,const I& index) :cont_(&cont){
typename I::const_iterator it = index.begin();
typename I::const_iterator end = index.end();
for(;it!=end; ++it){
index_.push_back(*it);
}
}
iterator begin(){
return make_reorient_iterator(cont_->begin()-cont_-
remove_count(),index_.begin());
}
iterator end(){
return make_reorient_iterator(cont_->begin()-cont_-
remove_count(),index_.end());
}
reverse_iterator rbegin(){
return std::reverse_iterator<iterator>(rend());
}
reverse_iterator rend(){
return std::reverse_iterator<iterator>(rbegin());
}
private:
index_t index_;
C* cont_;
};
int main(){///test
using namespace std;
using namespace boost::assign;
using namespace boost::lambda;
deque<int> v;
v+=0,10,20,30,40,50,60,70,80,90;
memory_vector<int> mv = v;
vector<std::size_t> iv;
iv+=1,3,6,7,8;
typedef reorient_view<memory_vector<int> > MIVIEW;
typedef reorient_view<deque<int> > IVIEW;
IVIEW view(v,iv);
MIVIEW mview(mv,iv);
cout<<"v: "; for_each(v.begin(),v.end(),cout<<_1<<" "); cout<<endl;
cout<<"rev v:";for_each(v.rbegin(),v.rend(),cout<<_1<<" ");
cout<<endl;
cout<<"iv: ";for_each(iv.begin(),iv.end(),cout<<_1<<" ");cout<<endl;
cout<<"mv: ";for_each(mv.begin(),mv.end(),cout<<_1<<" ");cout<<endl;
cout<<"rev mv: ";for_each(mv.rbegin(),mv.rend(),cout<<_1<<"
");cout<<endl;
cout<<"view: ";for_each(view.begin(),view.end(),std::cout<<_1<<" ");
cout<<endl;
cout<<"mview: ";for_each(mview.begin(),mview.end(),std::cout<<_1<<"
"); cout<<endl;
mv.pop_front(); v.pop_front();
cout<<"view: ";for_each(view.begin(),view.end(),std::cout<<_1<<" ");
cout<<endl;
cout<<"mview: ";for_each(mview.begin(),mview.end(),std::cout<<_1<<"
"); cout<<endl;
//cout<<"rev view:
";for_each(view.rbegin(),view.rend(),std::cout<<_1<<" "); cout<<endl;
std::system("PAUSE");
}

thanks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top