//
// header.hpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2009,2010 Dean Michael Berris (mikhailberis@gmail.com)
// Copyright (c) 2009 Tarroo, Inc.
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HEADER_HPP_20101122
#define BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HEADER_HPP_20101122

#include <boost/network/traits/string.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/network/support/is_default_wstring.hpp>
#include <boost/network/support/is_default_wstring.hpp>

namespace boost {
namespace network {
namespace http {

template <class Tag>
struct unsupported_tag;

struct request_header_narrow {
  typedef std::string string_type;
  std::string name, value;
};

struct request_header_wide {
  typedef std::wstring string_type;
  std::wstring name, value;
};

template <class Tag>
struct request_header
    : mpl::if_<is_default_string<Tag>, request_header_narrow,
               typename mpl::if_<is_default_wstring<Tag>, request_header_wide,
                                 unsupported_tag<Tag> >::type> {};

inline void swap(request_header_narrow& l, request_header_narrow& r) {
  swap(l.name, r.name);
  swap(l.value, r.value);
}

inline void swap(request_header_wide& l, request_header_wide& r) {
  swap(l.name, r.name);
  swap(l.value, r.value);
}

struct response_header_narrow {
  typedef std::string string_type;
  std::string name, value;
};

struct response_header_wide {
  typedef std::wstring string_type;
  std::wstring name, value;
};

template <class Tag>
struct response_header
    : mpl::if_<is_default_string<Tag>, response_header_narrow,
               typename mpl::if_<is_default_wstring<Tag>, response_header_wide,
                                 unsupported_tag<Tag> >::type> {};

inline void swap(response_header_narrow& l, response_header_narrow& r) {
  std::swap(l.name, r.name);
  std::swap(l.value, r.value);
}

inline void swap(response_header_wide& l, response_header_wide& r) {
  std::swap(l.name, r.name);
  std::swap(l.value, r.value);
}

}  // namespace http

}  // namespace network

}  // namespace boost

BOOST_FUSION_ADAPT_STRUCT(boost::network::http::request_header_narrow,
                          (std::string, name)(std::string, value))

BOOST_FUSION_ADAPT_STRUCT(boost::network::http::request_header_wide,
                          (std::wstring, name)(std::wstring, value))

BOOST_FUSION_ADAPT_STRUCT(boost::network::http::response_header_narrow,
                          (std::string, name)(std::string, value))

BOOST_FUSION_ADAPT_STRUCT(boost::network::http::response_header_wide,
                          (std::wstring, name)(std::wstring, value))

#endif  // BOOST_NETWORK_PROTOCOL_HTTP_MESSAGE_HEADER_HPP_20101122
