/*
IoBind Library License:
--------------------------
The zlib/libpng License Copyright (c) 2003 Jonathan de Halleux
This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution
*/
#ifndef IOBIND_SEQUENCE_POLICY_HPP
#define IOBIND_SEQUENCE_POLICY_HPP
#include <boost/call_traits.hpp>
#include <string>
#include <iobind/policy.hpp>
#include <iobind/string_policy.hpp>
#include <iobind/item_policy_property.hpp>
#include <iobind/item_decorators_property.hpp>
#include <iobind/sequence_container_parser.hpp>
namespace iobind{
namespace detail{
template<
typename ItemPolicy
>
class sequence_to_string_policy:
public property::item_policy_property<ItemPolicy>,
public property::item_decorators_property
{
public:
typedef property::item_policy_property<ItemPolicy> item_policy_property_type;
typedef property::item_decorators_property item_decorators_property_type;
typedef std::string string_type;
typedef std::string return_type;
typedef std::string const& string_param_type;
typedef typename boost::call_traits<ItemPolicy>::const_reference policy_const_reference;
sequence_to_string_policy(
policy_const_reference item_policy_,
string_param_type begin_,
string_param_type delimiter_,
string_param_type end_,
size_t const items_per_line_
)
:
item_policy_property_type(item_policy_),
item_decorators_property_type(begin_,delimiter_,end_),
m_items_per_line(items_per_line_)
{};
template<typename Iterator>
return_type encode( Iterator begin_, Iterator end_ ) const
{
if (begin_ == end_)
return return_type();
std::ostringstream output;
size_t i=0;
Iterator it = begin_;
output<<get_items_begin()<<get_item_policy().encode(*it);
++it, ++i;
while (it != end_)
{
output<<get_items_delimiter()<<get_item_policy().encode(*it);
if (i%m_items_per_line == 0)
output<<std::endl;
++it, ++i;
}
output<<get_items_end();
return output.str();
};
size_t const get_items_per_line() const { return m_items_per_line;};
private:
size_t m_items_per_line;
};
template<
typename Container,
typename ItemPolicy
>
class sequence_from_string_policy:
public property::item_policy_property<ItemPolicy>,
public property::item_decorators_property
{
public:
typedef property::item_policy_property<ItemPolicy> item_policy_property_type;
typedef property::item_decorators_property item_decorators_property_type;
typedef std::string string_type;
typedef std::string const& string_param_type;
typedef typename boost::call_traits<Container>::value_type container_type;
typedef typename boost::call_traits<Container>::value_type return_type;
typedef typename boost::call_traits<ItemPolicy>::const_reference policy_const_reference;
sequence_from_string_policy(
policy_const_reference item_policy_,
string_param_type begin_,
string_param_type delimiter_,
string_param_type end_)
:
item_policy_property_type(item_policy_),
item_decorators_property_type(begin_,delimiter_,end_)
{};
return_type encode( const std::string& str_ ) const
{
container_type container;
//boost::spirit::parse_info<> info =
parser::build_sequence_from_string(
str_,
container,
get_item_policy(),
get_items_begin(),
get_items_delimiter(),
get_items_end()
);
return container;
};
};
}; // detail
template<
typename ItemPolicy
>
struct sequence_to_string :
detail::policy_cons< detail::sequence_to_string_policy<ItemPolicy> , detail::identity_policy >
{
typedef sequence_to_string<ItemPolicy> type;
typedef type& reference;
typedef type const& const_reference;
typedef std::string string_param_type;
typedef typename boost::call_traits<ItemPolicy>::const_reference policy_const_reference;
typedef detail::sequence_to_string_policy<ItemPolicy> sequence_to_string_policy_type;
typedef detail::policy_cons< sequence_to_string_policy_type , detail::identity_policy > policy_type;
sequence_to_string(
policy_const_reference policy_,
string_param_type begin_ = "(",
string_param_type delimiter_ = ",",
string_param_type end_ = ")",
size_t const items_per_line_ = 10
)
: policy_type(
sequence_to_string_policy_type(policy_,begin_,delimiter_,end_,items_per_line_),
detail::identity_policy()
)
{};
// set items per line
type set_items_per_line( size_t const items_per_line_) const
{
return type(
get_head().get_item_policy(),
get_head().get_items_begin(),
get_head().get_items_delimiter(),
get_head().get_items_end(),
items_per_line_
);
}
// set decorators
type set_item_decorators(
string_param_type begin_,
string_param_type delimiter_,
string_param_type end_
) const
{
return type(
get_head().get_item_policy(),
begin_,
delimiter_,
end_,
get_head().get_items_per_line()
);
};
// replaces the ineer policy
template<
typename H,
typename T
>
sequence_to_string< detail::policy_cons<H,T> > change_item_policy( detail::policy_cons<H,T> const& policy_) const
{
return sequence_to_string< detail::policy_cons<H,T> >(
policy_,
get_head().get_items_begin(),
get_head().get_items_delimiter(),
get_head().get_items_end(),
get_head().get_items_per_line()
);
};
// replaces the ineer policy
template<
typename H,
typename T
>
sequence_to_string< detail::policy_cons<H,T> > operator << ( detail::policy_cons<H,T> const& policy_) const
{
return change_item_policy(policy_);
};
};
template<
typename Container,
typename ItemPolicy
>
struct sequence_from_string :
detail::policy_cons< detail::sequence_from_string_policy< Container, ItemPolicy > , detail::identity_policy >
{
typedef sequence_from_string<Container,ItemPolicy> type;
typedef type& reference;
typedef type const& const_reference;
typedef std::string string_param_type;
typedef typename boost::call_traits<ItemPolicy>::const_reference policy_const_reference;
typedef detail::sequence_from_string_policy< Container, ItemPolicy > sequence_from_string_policy_type;
typedef detail::policy_cons<
sequence_from_string_policy_type ,
detail::identity_policy > policy_type;
sequence_from_string(
policy_const_reference policy_,
string_param_type begin_ = "(",
string_param_type delimiter_ = ",",
string_param_type end_ = ")"
)
: policy_type(
sequence_from_string_policy_type(
policy_,
begin_,
delimiter_,
end_),
detail::identity_policy()
)
{};
// set decorators
type set_item_decorators(
string_param_type begin_,
string_param_type delimiter_,
string_param_type end_
) const
{
return type(
get_head().get_item_policy(),
begin_,
delimiter_,
end_
);
};
// replaces the inner policy
template<
typename H,
typename T
>
sequence_from_string<Container, detail::policy_cons<H,T> > change_item_policy( detail::policy_cons<H,T> const& policy_) const
{
return sequence_from_string<Container, detail::policy_cons<H,T> >(
policy_,
get_head().get_items_begin(),
get_head().get_items_delimiter(),
get_head().get_items_end()
);
};
// replaces the ineer policy
template<
typename H,
typename T
>
sequence_from_string<Container, detail::policy_cons<H,T> > operator << ( detail::policy_cons<H,T> const& policy_) const
{
return change_item_policy(policy_);
};
// replace the container type
template<typename C>
sequence_from_string<C, ItemPolicy > change_container( C const& dummy_c) const
{
return sequence_from_string<C, ItemPolicy >(
get_head().get_item_policy(),
get_head().get_items_begin(),
get_head().get_items_delimiter(),
get_head().get_items_end()
);
};
template<typename C>
sequence_from_string<C, ItemPolicy > operator % ( C const& dummy_c) const
{
return change_container(dummy_c);
};
};
typedef sequence_to_string<to_string_p_type> sequence_to_string_p_type;
const sequence_to_string_p_type sequence_to_string_p = sequence_to_string_p_type( to_string_p );
typedef sequence_from_string<std::vector<std::string>,to_string_p_type> sequence_from_string_p_type;
const sequence_from_string_p_type sequence_from_string_p = sequence_from_string_p_type( to_string_p );
template<typename Policy>
sequence_to_string<Policy> sequence_to_string_b(
Policy const& policy_,
std::string const& begin_ = "(",
std::string const& delimiter_ = ",",
std::string const& end_ = ")",
size_t const items_per_line_ = 10
)
{
return sequence_to_string<Policy>(policy_,begin_,delimiter_,end_,items_per_line_);
};
template<typename Container,typename Policy>
sequence_from_string<Container,Policy> sequence_from_string_b(
Container const& container_,
Policy const& policy_,
std::string const& begin_ = "",
std::string const& delimiter_ = ",",
std::string const& end_ = ""
)
{
return sequence_from_string<Container, Policy>(policy_,begin_,delimiter_,end_);
};
}; // iobind
#endif