Click here to Skip to main content
15,884,628 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 78.8K   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_POLICY_HPP
#define IOBIND_POLICY_HPP

#include <boost/mpl/if.hpp>
#include <boost/format.hpp>
#include <boost/call_traits.hpp>
#include <boost/type_traits/is_same.hpp>
#include <iobind/types.hpp>
#include <iobind/pair_policy_property.hpp>

namespace iobind{
namespace detail{
	struct identity_policy;

	template<
		typename FirstPolicy,
		typename SecondPolicy
	>
	class concatenation_policy:
		public property::pair_policy_property<FirstPolicy,SecondPolicy>
	{
	public:
		typedef typename property::pair_policy_property<FirstPolicy,SecondPolicy> pair_policy_property_type;
		typedef typename first_policy_type::return_type return_type;

		explicit concatenation_policy(
			typename pair_policy_property_type::first_policy_const_reference first_policy_,
			typename pair_policy_property_type::second_policy_const_reference second_policy_
			)
			:
			pair_policy_property_type(first_policy_,second_policy_)
			{};

			template<typename T>
			return_type encode(T const& value_) const
			{
				return get_first_policy().encode(value_) + get_second_policy().encode(value_);
			};
	};

	template<
		typename FirstPolicy,
		typename SecondPolicy
	>
	class chain_policy:
		public property::pair_policy_property<FirstPolicy,SecondPolicy>
	{
	public:
		typedef typename property::pair_policy_property<FirstPolicy,SecondPolicy> pair_policy_property_type;
		typedef typename second_policy_type::return_type return_type;

		explicit chain_policy(
			typename pair_policy_property_type::first_policy_const_reference first_policy_,
			typename pair_policy_property_type::second_policy_const_reference second_policy_
			)
			:
			pair_policy_property_type(first_policy_,second_policy_)
			{};

			template<typename T>
			return_type encode(T const& value_) const
			{
				get_first_policy().encode(value_);
				return get_second_policy().encode(value_);
			};
	};

	template<class H, class T>
	class policy_cons
	{
	public:
		typedef policy_cons<H,T> type;
		typedef typename boost::call_traits<H>::value_type head_type;
		typedef typename boost::call_traits<H>::const_reference head_const_reference;
		typedef typename boost::call_traits<T>::value_type tail_type;
		typedef typename boost::call_traits<T>::const_reference tail_const_reference;

		typedef typename ::boost::mpl::if_<
				boost::is_same<tail_type, identity_policy>,
				typename head_type::return_type, 
				typename tail_type::return_type
			>::type return_type;

		policy_cons(){};
		policy_cons( head_const_reference head_, tail_const_reference tail_)
			: m_head(head_), m_tail(tail_){};

		head_const_reference get_head() const {	return m_head;};
		tail_const_reference get_tail() const {	return m_tail;};

		template<
			typename U
		>
		policy_cons<U, policy_cons<H,T> > chain_with( policy_cons<U,identity_policy> const& policy_ ) const
		{
			return policy_cons<U, policy_cons<H,T> >( policy_.get_head(), *this  );
		};

		template<
			typename U
		>
		policy_cons<U, policy_cons<H,T> > operator * ( policy_cons<U,identity_policy> const& policy_ ) const
		{
			return chain_with( policy_  );
		};

		template<
				typename Policy
		>
		policy_cons<
			concatenation_policy< policy_cons<H,T>, Policy >,
			identity_policy
			> operator + ( Policy const& policy_ ) const
		{
			return policy_cons<
			concatenation_policy< policy_cons<H,T>, Policy >,
			identity_policy
				>( 
					concatenation_policy< policy_cons<H,T>, Policy >(
						*this, policy_ 
						),
					identity_policy()
				);
		};

		template<
				typename Policy
		>
		policy_cons<
			chain_policy< policy_cons<H,T>, Policy >,
			identity_policy
			> operator && ( Policy const& policy_ ) const
		{
			return policy_cons<
			chain_policy< policy_cons<H,T>, Policy >,
			identity_policy
				>( 
					chain_policy< policy_cons<H,T>, Policy >(
						*this, policy_ 
						),
					identity_policy()
				);
		};

		template<typename Value>
		return_type encode( Value const& value_) const
		{
			return m_tail.encode(
						m_head.encode(value_) 
						);
		};

		template<typename IteratorT>
		return_type encode(
			IteratorT const& begin_,
			IteratorT const& end_) const
		{
			return m_tail.encode(
						m_head.encode( begin_, end_ ) 
						);
		};

	private:
		head_type m_head;
		tail_type m_tail;
	};

	struct identity_policy 
	{
			typedef identity_policy type;
			typedef detail::null_type return_type;	

			explicit identity_policy(){};

			template<typename Value>
			Value const& encode(Value const& value_) const
			{
				return value_;
			};
	};

	const identity_policy identity_policy_p = identity_policy();
		
	template<typename T>
	struct typed_identity_policy
	{
			typedef typed_identity_policy<T> type;
			typedef typename boost::call_traits<T>::param_type return_type;	
			typedef typename boost::call_traits<T>::param_type param_type;	

			return_type encode(param_type value_) const
			{
				return value_;
			};
	};


};// detail
template<
	typename T
>
struct identity : detail::policy_cons< detail::typed_identity_policy<T> , detail::identity_policy>
{
	typedef identity<T> type;
};

template<
	typename U,
	typename H
>
struct policy_cons_traits
{
	typedef detail::policy_cons< U, detail::policy_cons<H, detail::identity_policy> > value_type;
	typedef detail::policy_cons< U, detail::policy_cons<H, detail::identity_policy> > const& param_type;
	typedef detail::policy_cons< U, detail::policy_cons<H, detail::identity_policy> > & reference;
	typedef detail::policy_cons< U, detail::policy_cons<H, detail::identity_policy> > const& const_reference;
};

template<
	typename Value,
	typename Policy
>
typename Policy::return_type encode(Value const& value_, Policy const& policy_)
{
	detail::policy_cons<Policy, detail::identity_policy> po(policy_, detail::identity_policy());

	return po.encode(value_);
};


template<
	typename Iterator,
	typename Policy
>
typename Policy::return_type encode(Iterator begin_, Iterator end_, Policy const& policy_)
{
	detail::policy_cons<Policy, detail::identity_policy> po(policy_, detail::identity_policy());

	return po.encode(begin_, 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