How to improve the functionality, exception safeness and other aspects of the following container adaptors?
Allows to write more generic code (not working for, say, <set>):
#include <utility>
#include <iterator>
#include <type_traits>
template< typename container, bool = std::is_const< std::remove_reference_t< container > >::value >
struct consumable_container;
template< typename container >
struct consumable_container< container, false >
{
    consumable_container(container && _container) noexcept
        : container_(std::forward< container >(_container))
    { ; }
    auto
    begin() noexcept
    {
        return std::make_move_iterator(std::begin(container_));
    }
    auto
    end() noexcept
    {
        return std::make_move_iterator(std::end(container_));
    }
private :
    container container_;
};
template< typename container >
struct consumable_container< container, true >
{
    static_assert(!std::is_rvalue_reference< container >::value);
    consumable_container(container && _container) noexcept
        : container_(std::forward< container >(_container))
    { ; }
    auto
    begin() const noexcept
    {
        return std::cbegin(container_);
    }
    auto
    end() const noexcept
    {
        return std::cend(container_);
    }
private :
    container container_;
};
template< typename container >
consumable_container< container >
move_if_not_const(container && _container) noexcept
{
    return std::forward< container >(_container);
}
// some generic code
#include <list>
template< typename container >
auto
transform_to_list(container && _container) noexcept
{
    static_assert(std::is_reference< container >::value || !std::is_const< container >::value);
    std::list< typename std::remove_reference_t< container >::value_type > list_;
    for (auto && value_ : move_if_not_const(std::forward< container >(_container))) {
        list_.push_back(std::forward< decltype(value_) >(value_));
    }
    return list_;
}
// testing data type
#include <iostream>
struct A
{
    A() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
    ~A() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
    A(A const &) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
    A(A &) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
    A(A &&) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
    A & operator = (A const &) { std::cout << __PRETTY_FUNCTION__ << std::endl; return *this; }
    A & operator = (A &) { std::cout << __PRETTY_FUNCTION__ << std::endl; return *this; }
    A & operator = (A &&) { std::cout << __PRETTY_FUNCTION__ << std::endl; return *this; }
};
// testing
#include <deque>
#include <forward_list>
#include <vector>
#include <cstdlib>
int
main()
{
    {
        std::deque< A > const deque_(1);
        std::list< A > ld_ = transform_to_list(deque_);
    }
    std::cout << std::endl;
    {
        std::forward_list< A > forward_list_;
        forward_list_.push_front(A{});
        std::list< A > ls_ = transform_to_list(forward_list_);
    }
    std::cout << std::endl;
    {
        std::vector< A > vector_;
        vector_.push_back(A{});
        std::list< A > lv_ = transform_to_list(std::move(vector_));
    }
    return EXIT_SUCCESS;
}
Allows to enumerate elements in reverse order:
#include <utility>
#include <iterator>
template< typename container >
struct reversed_container
{
    reversed_container(container && _container) noexcept
        : container_(std::forward< container >(_container))
    { ; }
    auto
    begin() noexcept
    {
        return std::rbegin(container_);
    }
    auto
    end() noexcept
    {
        return std::rend(container_);
    }
private :
    container container_;
};
template< typename container >
reversed_container< container >
reverse(container && _container) noexcept
{
    return std::forward< container >(_container);
}
// testing
#include <iostream>
#include <vector>
#include <cstdlib>
int
main()
{
    std::vector< int > vector_({1, 2, 3, 4, 5});
    // using
    for (int i : reverse(vector_)) {
        std::cout << i << std::endl;
    }
    return EXIT_SUCCESS;
}
Allows to print list of elements with delimiter (without trailing delimiter):
#include <utility>
#include <iterator>
template< typename container >
struct head_container
{
    head_container(container && _container) noexcept
        : container_(std::forward< container >(_container))
    { ; }
    auto
    begin() noexcept
    {
        return std::begin(container_);
    }
    auto
    end() noexcept
    {
        auto last = std::end(container_);
        if (last == std::begin(container_)) {
            return last;
        } else {
            return std::prev(last);
        }
    }
private :
    container container_;
};
template< typename container >
head_container< container >
head(container && _container) noexcept
{
    return std::forward< container >(_container);
}
// testing
#include <iostream>
#include <vector>
#include <cstdlib>
int
main()
{
    std::vector< int > vector_({1, 2, 3, 4, 5});
    // using
    if (!vector_.empty()) {
        for (int i : head(vector_)) {
            std::cout << i << ", ";
        }
        std::cout << vector_.back() << std::endl;
    }
    return EXIT_SUCCESS;
}
Allows to treat first element in special way:
#include <utility>
#include <iterator>
template< typename container >
struct tail_container
{
    tail_container(container && _container) noexcept
        : container_(std::forward< container >(_container))
    { ; }
    auto
    begin() noexcept
    {
        auto first = std::begin(container_);
        if (first == std::end(container_)) {
            return first;
        } else {
            return std::next(first);
        }
    }
    auto
    end() noexcept
    {
        return std::end(container_);
    }
private :
    container container_;
};
template< typename container >
tail_container< container >
tail(container && _container) noexcept
{
    return std::forward< container >(_container);
}
// testing
#include <iostream>
#include <vector>
#include <cstdlib>
int
main()
{
    std::vector< int > vector_({1, 2, 3, 4, 5});
    // using
    if (!vector_.empty()) {
        for (int i : tail(vector_)) {
            vector_.front() += i;
        }
        std::cout << vector_.front() << std::endl;
    }
    return EXIT_SUCCESS;
}
    
transform_to_list()available via constructor and iterators.reverse()is available by directly callingrbegin() andrend()` or using arangeadapter from boost. Yourhead()and tail is better adapted using an iterator adapter see stackoverflow.com/a/1430892/14065 \$\endgroup\$