Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > having an alternate function based on some trait .. exactly how to do?

Reply
Thread Tools

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

 
 
abir
Guest
Posts: n/a
 
      03-28-2008
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:ait<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:ait<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
 
Reply With Quote
 
 
 
 
gnuyuva
Guest
Posts: n/a
 
      03-28-2008
On Mar 28, 3:56 pm, abir <(E-Mail Removed)> wrote:
> 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:ait<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:ait<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.

> thanks
> abir

 
Reply With Quote
 
 
 
 
abir
Guest
Posts: n/a
 
      03-28-2008
On Mar 28, 4:48 pm, gnuyuva <(E-Mail Removed)> wrote:
> On Mar 28, 3:56 pm, abir <(E-Mail Removed)> wrote:
>
>
>
> > 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:ait<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:ait<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.
>
> > thanks
> > abir

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:ointer 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:ointer 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:ointer 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:ointer 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
can I have trait based friendship for a class abir C++ 3 02-27-2008 09:28 AM
what's 'alternate' in <link rel=alternate>? Chris ASP .Net 2 03-04-2007 04:45 PM
Alternate initializers or alternate class? transfire@gmail.com Ruby 10 07-17-2006 03:20 AM
trait technique? Patrick Guio C++ 7 12-21-2004 11:27 PM



Advertisments