insert/push_back/push_front range extension

Add range-based non-member non-friend insert extension, push_back/push_front utilities that build upon it, and RANGE_RETURNS utility macro.

Closes #4 .
 I just cannot find anything to add as refinement of Iterable to make a
generic Container concept (and this is why I stayed with Iterable).

I have a lot of questions relating ownership and monadic operations that
have to do with a container concept.

Starting with ownership, what do we mean by "a container owns its elements"
? Do they really?

In particular I think of e.g. a std::vector with a Boost.Interprocess
shared-memory allocator where you have multiple different applications that
can append and remove elements from such a "container" but only when the
last one exits its memory is freed. Who owns those elements? (It looks to
me that it is the shared memory allocator who owns them, not the
container).

So, what role do possibly stateful allocators play in a container concept?

One thing that distinguishes a container of immutable integers from
view::iota() is that we can take the address of the elements of the
container in memory. Is this important in the definition of a container? If
we don't consider address but use for access "the n-th container element"
then the container and the "generator" function object are very similar. Is
iota a container of immutable elements to which I cannot take the address
of? In particular when thinking about Boost.MPL we use the n-th element way
of referring to elements since we cannot take the address of types. Is an
mpl::vector of mpl::int_ a container or not?

It looks like the word container is extremely overloaded. Maybe this is why
I have so many questions.

Following with my thoughts about monadic operations. In our parlance,
Iterable (begin + end) + std::transform represent the monadic fmap. Since
containers, and anything that wraps anything (T*, unique/shared_ptr,
optional, expected, future, atomic...), are just monads, should the
Container concept define some unit and join/return/bind? Would Extensible
(a way to insert something into some object wrapper) mean anything for say
a std::future(when_all/when_any seem like a way to insert multiple futures
into a future)? I don't think so but maybe someone with Haskell experience
might be worth consulting here.

Finally.. In C++ 11 most of the requirements on the types of a container
(and thus on the container type itself) have been shifted to sets of
container operations. For example vector<T>(n) requires T to be default
constructible but vector<T> does not.

Maybe it would be better to focus on the concepts that exist for such
groups of operations on containers (like Extensible) which do have concrete
requirements. I can't find any examples of things that might model
`Extensible` but not `Iterable` but this is not a good enough reason to
make Extensible refine Iterable.


On Tue, Sep 23, 2014 at 12:30 AM, Eric Niebler <notifications@github.com>
wrote:

> In include/range/v3/extension/push_back.hpp:
>
> > +    inline namespace v3
> > +    {
> > +        struct push_back_fn
> > +        {
> > +            template <typename I, typename S, typename O,
> > +                      typename OIt = decltype(end(std::declval<O>())),
> > +                      CONCEPT_REQUIRES_(Insertable<O, OIt, I, S>())>
> > +            auto operator()(O &to, I &&from_begin, S &&from_end) const
> > +                RANGE_RETURNS(insert(to, end(to), std::forward<I>(from_begin),
> > +                                     std::forward<S>(from_end)));
> > +
> > +            template <typename I, typename O,
> > +                      typename OIt = decltype(end(std::declval<O>())),
> > +                      CONCEPT_REQUIRES_(Insertable<O, OIt, I>())>
> > +            auto operator()(O &to, I &&from) const
> > +                RANGE_RETURNS(insert(to, end(to), std::forward<I>(from)));
>
>  Does view::join degrade the traversal category of a range? If I join two
> RandomAccessRanges do I get a RandomAccessRange or a BidirectionalRange?
>
> You get a RandomAccessRange, as you should.
>
> Since, at this moment, it seems like all the models of Extensible will
> also be Containers, I'd rather we defined the Container concept and made
> ExtensibleContainer refine that.
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/ericniebler/range-v3/pull/44/files#r17882761>.
>