Click here to Skip to main content
15,897,371 members
Articles / Programming Languages / C++

IoBind, a serializer code factory.

Rate me:
Please Sign up or sign in to vote.
4.89/5 (10 votes)
29 Jun 20037 min read 79.1K   763   29  
IoBind proposes a new approach to object serialization.
/*
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


By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Engineer
United States United States
Jonathan de Halleux is Civil Engineer in Applied Mathematics. He finished his PhD in 2004 in the rainy country of Belgium. After 2 years in the Common Language Runtime (i.e. .net), he is now working at Microsoft Research on Pex (http://research.microsoft.com/pex).

Comments and Discussions