/*
*************************************************************************************************

stlコンテナをfluent interface化するラッパ

*************************************************************************************************
*/

#pragma once

#include <vector>
#include <set>
#include <map>
#include <list>
#include <string>


namespace util
{


namespace fl
{

template<typename T>
void AddElement(std::vector<T>& v, const T& val)
{
	v.push_back(val);
}

template<typename T>
void AddElement(std::list<T>& l, const T& val)
{
	l.push_back(val);
}

template<typename T>
void AddElement(std::set<T>& s, const T& val)
{
	s.insert(val);
}

template<typename T, typename U>
void AddElement(std::map<T, U>& m, const std::pair<T, U>& val)
{
	m.insert(val);
}

void AddElement(std::string& s, const char* str)
{
	s += str;
}

void AddElement(std::string& s, const std::string& str)
{
	s += str;
}

void AddElement(std::wstring& s, const wchar_t* str)
{
	s += str;
}

void AddElement(std::wstring& s, const std::wstring& str)
{
	s += str;
}

}


template<typename T>
class FluentInterface
{
public:
	FluentInterface(T& container) :
		_container(&container)
	{}

	template<typename U>
	FluentInterface<T>& operator<<(const U& val)
	{
		fl::AddElement(*_container, val);
		return *this;
	}

private:
	T* _container;
};

template<typename T>
FluentInterface<T> fluent(T& container)
{
	return FluentInterface<T>(container);
}


}
