boost::assign作ってみた

意外と簡単に作れましたが、初めて1ファイルで提供できないライブラリになっちゃいました。


list_inserter.hpp

#ifndef SHAND_ASSIGN_LIST_INSERTER_INCLUDE
#define SHAND_ASSIGN_LIST_INSERTER_INCLUDE

namespace shand {

namespace assign_detail {

// push_backメンバ呼び出し用ファンクタ
template <class Container>
class call_push_back {
    Container& container_;
public:
    typedef Container container_type;

    call_push_back(Container& container)
        : container_(container) {}

    template <class Type>
    void operator()(Type value)
    {
        container_.push_back(value);
    }
};

// pushメンバ呼び出し用ファンクタ
template <class Container>
class call_push {
    Container& container_;
public:
    typedef Container container_type;

    call_push(Container& container)
        : container_(container) {}

    template <class Type>
    void operator()(Type value)
    {
        container_.push(value);
    }
};

// insertメンバ呼び出し用ファンクタ
template <class Container>
class call_insert {
    Container& container_;
public:
    typedef Container container_type;

    call_insert(Container& container)
        : container_(container) {}

    template <class Type>
    void operator()(Type value)
    {
        container_.insert(value);
    }
};

} // namespace shand::assign_detail


namespace assign {

template <class Inserter>
class list_inserter {
    Inserter inserter_;
public:
    list_inserter(typename Inserter::container_type& container)
        : inserter_(container) {}

    template <class Type>
    list_inserter& operator,(Type value)
    {
        inserter_(value);
        return *this;
    }

    template <class Type>
    list_inserter& operator()(Type value)
    {
        inserter_(value);
        return *this;
    }
};


template <class Container>
inline list_inserter<assign_detail::call_push_back<Container> >
push_back(Container& container)
{
    return list_inserter<assign_detail::call_push_back<Container> >(container);
}

template <class Container>
inline list_inserter<assign_detail::call_push<Container> >
push(Container& container)
{
    return list_inserter<assign_detail::call_push<Container> >(container);
}

template <class Container>
inline list_inserter<assign_detail::call_insert<Container> >
insert(Container& container)
{
    return list_inserter<assign_detail::call_insert<Container> >(container);
}

} // namespace shand::assign

} // namespace shand

#endif // SHAND_ASSIGN_LIST_INSERTER_INCLUDE

vector.hpp

#ifndef SHAND_ASSIGN_VECTOR_INCLUDE
#define SHAND_ASSIGN_VECTOR_INCLUDE

#include <vector>
#include "list_inserter.hpp"

namespace shand { namespace assign {

template <class Type>
inline list_inserter<assign_detail::call_push_back<std::vector<Type> > >
operator+=(std::vector<Type>& container, Type value)
{
    return push_back(container)(value);
}

}} // namespace shand::assign

#endif // SHAND_ASSIGN_VECTOR_INCLUDE

list.hpp

#ifndef SHAND_ASSIGN_LIST_INCLUDE
#define SHAND_ASSIGN_LIST_INCLUDE

#include <list>
#include "list_inserter.hpp"

namespace shand { namespace assign {

template <class Type>
inline list_inserter<assign_detail::call_push_back<std::list<Type> > >
operator+=(std::list<Type>& container, Type value)
{
    return push_back(container)(value);
}

}} // namespace shand::assign

#endif // SHAND_ASSIGN_LIST_INCLUDE

stack.hpp

#ifndef SHAND_ASSIGN_STACK_INCLUDE
#define SHAND_ASSIGN_STACK_INCLUDE

#include <stack>
#include "list_inserter.hpp"

namespace shand { namespace assign {

template <class Type>
inline list_inserter<assign_detail::call_push<std::stack<Type> > >
operator+=(std::stack<Type>& container, Type value)
{
    return push(container)(value);
}

}} // namespace shand::assign

#endif // SHAND_ASSIGN_STACK_INCLUDE

queue.hpp

#ifndef SHAND_ASSIGN_QUEUE_INCLUDE
#define SHAND_ASSIGN_QUEUE_INCLUDE

#include <queue>
#include "list_inserter.hpp"

namespace shand { namespace assign {

template <class Type>
inline list_inserter<assign_detail::call_push<std::queue<Type> > >
operator+=(std::queue<Type>& container, Type value)
{
    return push(container)(value);
}

}} // namespace shand::assign

#endif // SHAND_ASSIGN_QUEUE_INCLUDE

deque.hpp

#ifndef SHAND_ASSIGN_DEQUE_INCLUDE
#define SHAND_ASSIGN_DEQUE_INCLUDE

#include <deque>
#include "list_inserter.hpp"

namespace shand { namespace assign {

template <class Type>
inline list_inserter<assign_detail::call_push_back<std::deque<Type> > >
operator+=(std::deque<Type>& container, Type value)
{
    return push_back(container)(value);
}

}} // namespace shand::assign

#endif // SHAND_ASSIGN_DEQUE_INCLUDE

map.hpp

#ifndef SHAND_ASSIGN_MAP_INCLUDE
#define SHAND_ASSIGN_MAP_INCLUDE

#include <map>
#include "list_inserter.hpp"

namespace shand { namespace assign {

template <class Key, class Type, class Pair>
inline list_inserter<assign_detail::call_insert<std::map<Key, Type> > >
operator+=(std::map<Key, Type>& container, Pair value)
{
    return insert(container)(value);
}

template <class Key, class Type, class Pair>
inline list_inserter<assign_detail::call_insert<std::multimap<Key, Type> > >
operator+=(std::multimap<Key, Type>& container, Pair value)
{
    return insert(container)(value);
}

}} // namespace shand::assign

#endif // SHAND_ASSIGN_MAP_INCLUDE

set.hpp

#ifndef SHAND_ASSIGN_SET_INCLUDE
#define SHAND_ASSIGN_SET_INCLUDE

#include <set>
#include "list_inserter.hpp"

namespace shand { namespace assign {

template <class Key, class Type>
inline list_inserter<assign_detail::call_insert<std::set<Key> > >
operator+=(std::set<Key>& container, Type value)
{
    return insert(container)(value);
}

template <class Key, class Type>
inline list_inserter<assign_detail::call_insert<std::multiset<Key> > >
operator+=(std::multiset<Key>& container, Type value)
{
    return insert(container)(value);
}

}} // namespace shand::assign

#endif // SHAND_ASSIGN_SET_INCLUDE

std.hpp

#ifndef SHAND_ASSIGN_STANDARD_INCLUDE
#define SHAND_ASSIGN_STANDARD_INCLUDE

#include "vector.hpp"
#include "list.hpp"
#include "stack.hpp"
#include "queue.hpp"
#include "deque.hpp"
#include "map.hpp"
#include "set.hpp"

#endif // SHAND_ASSIGN_STANDARD_INCLUDE

サンプル

#include <string>
#include <shand/assign/vector.hpp>
#include <shand/assign/stack.hpp>
#include <shand/assign/map.hpp>

using namespace std;
using namespace shand::assign;

int main()
{
    vector<int> v;
    v += 3, 1, 4; // v.push_back

    stack<int> s;
    s += 3, 1, 4; // s.push

    map<int, string> m;
    m += make_pair(3, "a"), make_pair(1, "b"), make_pair(4, "c"); // m.insert

    return 0;
}

ライブラリまとめ