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 >autotransform_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>intmain(){    {        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>intmain(){    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>intmain(){    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>intmain(){    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;}
Container adaptors
c++;c++11;collections;c++14