//  (C) Copyright Jeremy Siek 2004
//  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_PROPERTY_HPP
#define BOOST_PROPERTY_HPP

#include <boost/mpl/bool.hpp>

namespace boost {

  struct no_property {
    typedef no_property tag_type;
    typedef no_property next_type;
    typedef no_property value_type;
    enum { num = 0 };
    typedef void kind;
  };

  template <class Tag, class T, class Base = no_property>
  struct property : public Base {
    typedef Base next_type;
    typedef Tag tag_type;
    typedef T value_type;
#if BOOST_WORKAROUND (__GNUC__, < 3)
    property() { }
#else
    property() : m_value() { }
#endif
    property(const T& v) : m_value(v) { }
    property(const T& v, const Base& b) : Base(b), m_value(v) { }
    // copy constructor and assignment operator will be generated by compiler

    T m_value;
  };

  // The BGL properties specialize property_kind and
  // property_num, and use enum's for the Property type (see
  // graph/properties.hpp), but the user may want to use a class
  // instead with a nested kind type and num.  Also, we may want to
  // switch BGL back to using class types for properties at some point.

  template <class PropertyTag>
  struct property_kind {
    typedef typename PropertyTag::kind type;
  };

  template <class P>
  struct has_property : boost::mpl::true_ {};
  template <>
  struct has_property<no_property> : boost::mpl::false_ {};

} // namespace boost

#include <boost/pending/detail/property.hpp>

namespace boost {

  template <class PropertyList, class Tag>
  struct property_value {
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
    typedef typename detail::build_property_tag_value_alist<PropertyList>::type AList;
    typedef typename detail::extract_value<AList,Tag>::type type;
#else
    typedef typename detail::build_property_tag_value_alist<PropertyList>::type AList;
    typedef typename detail::ev_selector<AList>::type Extractor;
    typedef typename Extractor::template bind_<AList,Tag>::type type;
#endif
  };

  template <class Tag2>
  inline detail::error_property_not_found
  get_property_value(const no_property& p, Tag2) {
    return detail::error_property_not_found();
  }

  template <class Tag1, class Tag2, class T1, class Base>
  inline typename property_value<property<Tag1,T1,Base>, Tag2>::type&
  get_property_value(property<Tag1,T1,Base>& p, Tag2 tag2) {
    BOOST_STATIC_CONSTANT(bool,
                          match = (detail::same_property<Tag1,Tag2>::value));
    typedef property<Tag1,T1,Base> Prop;
    typedef typename property_value<Prop, Tag2>::type T2;
    T2* t2 = 0;
    typedef detail::property_value_dispatch<match> Dispatcher;
    return Dispatcher::get_value(p, t2, tag2);
  }
  template <class Tag1, class Tag2, class T1, class Base>
  inline
  const typename property_value<property<Tag1,T1,Base>, Tag2>::type&
  get_property_value(const property<Tag1,T1,Base>& p, Tag2 tag2) {
    BOOST_STATIC_CONSTANT(bool,
                          match = (detail::same_property<Tag1,Tag2>::value));
    typedef property<Tag1,T1,Base> Prop;
    typedef typename property_value<Prop, Tag2>::type T2;
    T2* t2 = 0;
    typedef detail::property_value_dispatch<match> Dispatcher;
    return Dispatcher::const_get_value(p, t2, tag2);
  }

 namespace detail {

     /** This trait returns true if T is no_property. */
    template <typename T>
    struct is_no_property
        : mpl::bool_<is_same<T, no_property>::value>
    { };

#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
    /** @internal @name Retag Property List
     * This metafunction is used internally to normalize a property if it is
     * actually modeling a property. Specifically this is used in Boost.Graph
     * to map user-provided classes into bundled properties.
     */
    //@{
    // One base case of the recursive form (see below). This matches any
    // retag request that does not include a property<...> or no_property as
    // the FinalType. This is used for generating bundles in Boost.Graph.
    template<typename FinalTag, typename FinalType>
    struct retag_property_list
    {
        typedef property<FinalTag, FinalType> type;
        typedef FinalType retagged;
    };

    // Recursively retag the nested property list.
    template<typename FinalTag, typename Tag, typename T, typename Base>
    struct retag_property_list<FinalTag, property<Tag, T, Base> >
    {
    private:
        typedef retag_property_list<FinalTag, Base> next;

    public:
        typedef property<Tag, T, typename next::type> type;
        typedef typename next::retagged retagged;
    };

    // This base case will correctly deduce the final property type if the
    // retagged property is given in property form. This should not hide
    // the base case below.
    // NOTE: This addresses a problem of layering bundled properties in the BGL
    // where multiple retaggings will fail to deduce the correct retagged
    // type.
    template<typename FinalTag, typename FinalType>
    struct retag_property_list<FinalTag, property<FinalTag, FinalType> >
    {
    public:
        typedef property<FinalTag, FinalType> type;
        typedef FinalType retagged;
    };

    // A final base case of the retag_property_list, this will terminate a
    // properly structured list.
    template<typename FinalTag>
    struct retag_property_list<FinalTag, no_property>
    {
        typedef no_property type;
        typedef no_property retagged;
    };
    //@}
#endif
} // namespace detail

} // namesapce boost

#endif /* BOOST_PROPERTY_HPP */
