|
Boost Users : |
Subject: Re: [Boost-users] Ranges to Collections
From: Nathan Ridge (zeratul976_at_[hidden])
Date: 2011-06-07 00:33:04
I use this:
template <typename Range>
struct RangeWrapper
{
const Range& r;
template <typename Container>
operator Container() const
{
return Container(begin(r), end(r));
}
};
template <typename Range>
RangeWrapper<Range> range_to_container(const Range& r)
{
return RangeWrapper<Range>{r};
}
Simple but effective.
Regards,
Nate.
----------------------------------------
> Date: Tue, 7 Jun 2011 10:31:29 +0800
> From: qiaozhiqiang_at_[hidden]
> To: boost-users_at_[hidden]
> CC: mpbecey7gu_at_[hidden]
> Subject: Re: [Boost-users] Ranges to Collections
>
> Maybe you want make_vector() , make_list().
>
>
> #include
> #include
> #include
> #include
>
>
>
> #include // for test
>
>
>
> template
> T make_container(const SinglePassRange& from)
> {
> T c;
> boost::push_back(c, from);
> return move(c);
> }
>
> template
> std::vector make_vector(const SinglePassRange& from)
> {
> return make_container>(from);
> }
>
>
> template
> std::list make_list(const SinglePassRange& from)
> {
> return make_container>(from);
> }
>
>
>
> int main(int argc, _TCHAR* argv[])
> {
> std::vector vector1;
> vector1.push_back(1);
> vector1.push_back(2);
> vector1.push_back(3);
>
> std::list list1;
> list1.push_back(1);
> list1.push_back(2);
> list1.push_back(3);
>
> auto vector2 = make_container>(vector1 | boost::adaptors::reversed);
> auto vector3 = make_vector(vector1 | boost::adaptors::reversed);
> auto vector4 = make_vector(vector1);
>
> auto list2 = make_container>(list1 | boost::adaptors::reversed);
> auto list3 = make_list(list1 | boost::adaptors::reversed);
> auto list4 = make_list(list1);
>
> return 0;
> }
>
>
> > ------------------------------
> >
> > Message: 2
> > Date: Mon, 06 Jun 2011 11:00:29 -0500
> > From: "John M. Dlugosz"
> > To: boost-users_at_[hidden]
> > Subject: [Boost-users] Ranges to Collections
> > Message-ID: <15775-1307376032-823667_at_[hidden]>
> > Content-Type: text/plain; charset=UTF-8; format=flowed
> >
> > I like "ranges". When I first read the introduction to the ideas that would
> > become STL, I
> > did not like the use of begin/end iterators. Primarily, there is a possibility
> > of getting
> > them mixed up and the proposed library was explicitly not robust in the face
> > of being
> > passed bad parameters, such as not belonging to the same collection or not
> > having the end
> > after the begin. This was in direct contrast to the code I was promoting, which
> > stressed
> > API design that prevented errors from being possible, and strongly checking
> > for everything
> > else. The fact that they are not "functional" was harder to grasp exactly at
> > the time,
> > but it bothered me "in my gut".
> >
> > When I read about the Boost Range library and the C++0x adoption of the range
> > concept, I
> > felt this to be a long sought improvement and would dramatically improve my
> > use of STL.
> >
> > Suffice to say, I'm a fan of Ranges. In new work, and in refactoring and
> > improving code,
> > I expect ranges to be one of the pillars of improvement. I'm sad to see that
> > the draft
> > standard dropped most of the range stuff (presumably it needs Concepts) but
> > left in the
> > intrinsic for-each loop. Anyway, the concrete compiler I have to work with,
> > Visual Studio
> > 2010, doesn't include it. So Boost.Range to the rescue! Except... the
> > standard
> > containers like vector don't have constructors that take ranges.
> >
> > Consider something like:
> > vector retval (rangefunc | rangefilter);
> >
> > It really gets in the way to introduce a temporary variable of "some range type",
> > but I
> > see that the 'auto' feature comes to the rescue. I'm not used to having that
> > available,
> > so perhaps I'm over reacting.
> >
> > But, is there a way to bridge the gap?
> >
> > I take it patching the STL headers to add the missing constructors is frowned
> > upon. But
> > some syntactic sugar might get pretty close to that. First of all, what are
> > people doing
> > now? Maybe this has all be gone over before?
> >
> > I can see creating a derived class from each STL container. The sole purpose
> > of that
> > class is to have the range constructor, and then the resulting instance is used
> > as the
> > base class, passed somewhere or copied. So you might write, for the previous
> > example:
> > range_vector retval (rangefunc | rangefilter);
> >
> > and other code won't care about your derived class since it only existed
> > district from the
> > base class in order to add a constructor. In fact, a template might
> > systematically do
> > this to any class that has a constructor that takes two iterators:
> > rangeit> retval (rangefunc | rangefilter);
> >
> > This is less than desirable in cases where you were not going to state the type.
> > Say, a
> > return statement or parameter, where you would ideally have an implicit
> > conversion from a
> > range to the collection:
> > return (rangefunc | rangefilter); // give a "range" where collection is
> > expected
> >
> > Could a helper template be written that has a simple name and doesn't need to
> > be told the
> > types involved?
> > return range_to_collection (rangefunc | rangefilter);
> >
> > Perhaps this produces a temporary object that supports a templatized conversion
> > operator,
> > so it can continue when that is told the type desired. I can see a few
> > approaches,
> > depending on what the compiler would swallow. But, has anyone already done
> > this?
> >
> > ?John
> >
> >
> >
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net