// iobind library
//
// author: Jonathan de Halleux, 2003
#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>
namespace iobind{
namespace detail{
struct identity_policy;
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<class U>
policy_cons<U, policy_cons<H,T> > operator+( policy_cons<U,identity_policy> const& policy_ )
{
return policy_cons<U, policy_cons<H,T> >( policy_.get_head(), *this );
};
template<typename T>
return_type encode(boost::call_traits<T>::param_type value_) const
{
return m_tail.encode(
m_head.encode(value_)
);
};
template<typename Iterator>
return_type encode(
boost::call_traits<Iterator>::param_type begin_,
boost::call_traits<Iterator>::param_type end_) const
{
return m_tail.encode(
m_head.encode( begin_, end_ )
);
};
private:
head_type m_head;
tail_type m_tail;
};
struct identity_policy : policy_cons<null_type, null_type>
{
typedef identity_policy type;
typedef detail::null_type return_type;
template<typename T>
static T encode(T value)
{
return value;
};
};
};// detail
struct identity : detail::identity_policy {};
static const identity identity_p=identity();
template<
typename U,
typename H
>
struct policy_cons_traits
{
typedef boost::call_traits< detail::policy_cons< U, detail::policy_cons<H, detail::identity_policy> > >::value_type value_type;
typedef boost::call_traits< detail::policy_cons< U, detail::policy_cons<H, detail::identity_policy> > >::param_type param_type;
typedef boost::call_traits< detail::policy_cons< U, detail::policy_cons<H, detail::identity_policy> > >::reference reference;
typedef boost::call_traits< detail::policy_cons< U, detail::policy_cons<H, detail::identity_policy> > >::const_reference 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