// file      : xsd/cxx/tree/types.hxx
// author    : Boris Kolpackov <boris@codesynthesis.com>
// copyright : Copyright (c) 2005-2006 Code Synthesis Tools CC
// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file

#ifndef XSD_CXX_TREE_TYPES_HXX
#define XSD_CXX_TREE_TYPES_HXX

#include <cstdlib> // std::size_t
#include <string>
#include <ostream>

#include <xsd/cxx/xml/dom/elements.hxx>

#include <xsd/cxx/tree/elements.hxx>
#include <xsd/cxx/tree/containers.hxx>

#include <xsd/cxx/tree/buffer.hxx>

namespace xsd
{
  namespace cxx
  {
    namespace tree
    {
      // string
      //
      template <typename C>
      class string: public std::basic_string<C>, public simple_type

      {
      protected:
        typedef std::basic_string<C> primary_type;
        typedef std::basic_string<C> base_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        string ()
        {
        }

        string (C const* s)
            : base_type (s)
        {
        }

        string (C const* s, std::size_t n)
            : base_type (s, n)
        {
        }

        string (std::size_t n, C c)
            : base_type (n, c)
        {
        }

        string (primary_type const& str)
            : base_type (str)
        {
        }

        string (primary_type const& str,
                std::size_t pos,
                std::size_t n = primary_type::npos)
            : base_type (str, pos, n)
        {
        }

      public:
        string (string const& other, flags f = 0, type* container = 0)
            : base_type (other),
              simple_type (other, f, container)
        {
        }

        virtual string*
        _clone (flags f = 0, type* container = 0) const
        {
          return new string (*this, f, container);
        }

      public:
        string (xml::dom::element<C> const& e, flags f, type* container)
            : base_type (e.value ()), simple_type (e, f, container)
        {
        }

        string (xml::dom::attribute<C> const& a, flags f, type* container)
            : base_type (a.value ()), simple_type (a, f, container)
        {
        }

        string (std::basic_string<C> const& s,
                xml::dom::element<C> const* e,
                flags f,
                type* container)
            : base_type (s), simple_type (s, e, f, container)
        {
        }

      public:
        string&
        operator= (C c)
        {
          base () = c;
          return *this;
        }

        string&
        operator= (C const* s)
        {
          base () = s;
          return *this;
        }

        string&
        operator= (primary_type const& str)
        {
          base () = str;
          return *this;
        }

        // Implicit copy assignment operator.
        //
      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, string<C> const& v)
      {
        std::basic_string<C> const& r (v);
        return os << r;
      }


      // normalized_string: string
      //
      template <typename C>
      class normalized_string: public string<C>
      {
      protected:
        typedef string<C> base_type;
        typedef typename base_type::primary_type primary_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        normalized_string ()
        {
        }

        normalized_string (C const* s)
            : base_type (s)
        {
        }

        normalized_string (C const* s, std::size_t n)
            : base_type (s, n)
        {
        }

        normalized_string (std::size_t n, C c)
            : base_type (n, c)
        {
        }

        normalized_string (primary_type const& str)
            : base_type (str)
        {
        }

        normalized_string (primary_type const& str,
                           std::size_t pos,
                           std::size_t n = primary_type::npos)
            : base_type (str, pos, n)
        {
        }

      public:
        normalized_string (normalized_string const& other,
                           flags f = 0,
                           type* container = 0)
            : base_type (other, f, container)
        {
        }

        virtual normalized_string*
        _clone (flags f = 0, type* container = 0) const
        {
          return new normalized_string (*this, f, container);
        }

      public:
        normalized_string (xml::dom::element<C> const& e,
                           flags f,
                           type* container)
            : base_type (e, f, container)
        {
        }

        normalized_string (xml::dom::attribute<C> const& a,
                           flags f,
                           type* container)
            : base_type (a, f, container)
        {
        }

        normalized_string (std::basic_string<C> const& s,
                           xml::dom::element<C> const* e,
                           flags f,
                           type* container)
            : base_type (s, e, f, container)
        {
        }

      public:
        normalized_string&
        operator= (C c)
        {
          base () = c;
          return *this;
        }

        normalized_string&
        operator= (C const* s)
        {
          base () = s;
          return *this;
        }

        normalized_string&
        operator= (primary_type const& str)
        {
          base () = str;
          return *this;
        }

        // Implicit copy assignment operator.
        //
      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, normalized_string<C> const& v)
      {
        string<C> const& r (v);
        return os << r;
      }


      // token: normalized_string
      //
      template <typename C>
      class token: public normalized_string<C>
      {
      protected:
        typedef normalized_string<C> base_type;
        typedef typename base_type::primary_type primary_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        token ()
        {
        }

        token (C const* s)
            : base_type (s)
        {
        }

        token (C const* s, std::size_t n)
            : base_type (s, n)
        {
        }

        token (std::size_t n, C c)
            : base_type (n, c)
        {
        }

        token (primary_type const& str)
            : base_type (str)
        {
        }

        token (primary_type const& str,
               std::size_t pos,
               std::size_t n = primary_type::npos)
            : base_type (str, pos, n)
        {
        }

      public:
        token (token const& other, flags f = 0, type* container = 0)
            : base_type (other, f, container)
        {
        }

        virtual token*
        _clone (flags f = 0, type* container = 0) const
        {
          return new token (*this, f, container);
        }

      public:
        token (xml::dom::element<C> const& e, flags f, type* container)
            : base_type (e, f, container)
        {
        }

        token (xml::dom::attribute<C> const& a, flags f, type* container)
            : base_type (a, f, container)
        {
        }

        token (std::basic_string<C> const& s,
               xml::dom::element<C> const* e,
               flags f,
               type* container)
            : base_type (s, e, f, container)
        {
        }

      public:
        token&
        operator= (C c)
        {
          base () = c;
          return *this;
        }

        token&
        operator= (C const* s)
        {
          base () = s;
          return *this;
        }

        token&
        operator= (primary_type const& str)
        {
          base () = str;
          return *this;
        }

        // Implicit copy assignment operator.
        //
      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, token<C> const& v)
      {
        normalized_string<C> const& r (v);
        return os << r;
      }


      // nmtoken: token
      //
      template <typename C>
      class nmtoken: public token<C>
      {
      protected:
        typedef token<C> base_type;
        typedef typename base_type::primary_type primary_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        nmtoken (C const* s)
            : base_type (s)
        {
        }

        nmtoken (C const* s, std::size_t n)
            : base_type (s, n)
        {
        }

        nmtoken (std::size_t n, C c)
            : base_type (n, c)
        {
        }

        nmtoken (primary_type const& str)
            : base_type (str)
        {
        }

        nmtoken (primary_type const& str,
                 std::size_t pos,
                 std::size_t n = primary_type::npos)
            : base_type (str, pos, n)
        {
        }

      public:
        nmtoken (nmtoken const& other, flags f = 0, type* container = 0)
            : base_type (other, f, container)
        {
        }

        virtual nmtoken*
        _clone (flags f = 0, type* container = 0) const
        {
          return new nmtoken (*this, f, container);
        }

      public:
        nmtoken (xml::dom::element<C> const& e, flags f, type* container)
            : base_type (e, f, container)
        {
        }

        nmtoken (xml::dom::attribute<C> const& a, flags f, type* container)
            : base_type (a, f, container)
        {
        }

        nmtoken (std::basic_string<C> const& s,
                 xml::dom::element<C> const* e,
                 flags f,
                 type* container)
            : base_type (s, e, f, container)
        {
        }

      public:
        nmtoken&
        operator= (C c)
        {
          base () = c;
          return *this;
        }

        nmtoken&
        operator= (C const* s)
        {
          base () = s;
          return *this;
        }

        nmtoken&
        operator= (primary_type const& str)
        {
          base () = str;
          return *this;
        }

        // Implicit copy assignment operator.
        //
      };


      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, nmtoken<C> const& v)
      {
        token<C> const& r (v);
        return os << r;
      }


      // nmtokens: sequence<nmtoken>
      //
      template <typename C>
      class nmtokens: public simple_type, public sequence<nmtoken<C> >
      {
        typedef sequence<nmtoken<C> > base_type;

      public:
        nmtokens ()
        {
        }

        nmtokens (nmtokens const& other, flags f, type* container)
            : simple_type (other, f, container),
              base_type (other, f, container)
        {
        }

        virtual nmtokens*
        _clone (flags f = 0, type* container = 0) const
        {
          return new nmtokens (*this, f, container);
        }

      public:
        nmtokens (xml::dom::element<C> const& e, flags f, type* container)
            : simple_type (e, f, container), base_type (e, f, container)
        {
        }

        nmtokens (xml::dom::attribute<C> const& a, flags f, type* container)
            : simple_type (a, f, container), base_type (a, f, container)
        {
        }

        nmtokens (std::basic_string<C> const& s,
                  xml::dom::element<C> const* e,
                  flags f,
                  type* container)
            : simple_type (s, e, f, container), base_type (s, e, f, container)
        {
        }
      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, nmtokens<C> const& v)
      {
        sequence<nmtoken<C> > const& r (v);
        return os << r;
      }


      // name: token
      //
      template <typename C>
      class name: public token<C>
      {
      protected:
        typedef token<C> base_type;
        typedef typename base_type::primary_type primary_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        name (C const* s)
            : base_type (s)
        {
        }

        name (C const* s, std::size_t n)
            : base_type (s, n)
        {
        }

        name (std::size_t n, C c)
            : base_type (n, c)
        {
        }

        name (primary_type const& str)
            : base_type (str)
        {
        }

        name (primary_type const& str,
              std::size_t pos,
              std::size_t n = primary_type::npos)
            : base_type (str, pos, n)
        {
        }

      public:
        name (name const& other, flags f = 0, type* container = 0)
            : base_type (other, f, container)
        {
        }

        virtual name*
        _clone (flags f = 0, type* container = 0) const
        {
          return new name (*this, f, container);
        }

      public:
        name (xml::dom::element<C> const& e, flags f, type* container)
            : base_type (e, f, container)
        {
        }

        name (xml::dom::attribute<C> const& a, flags f, type* container)
            : base_type (a, f, container)
        {
        }

        name (std::basic_string<C> const& s,
              xml::dom::element<C> const* e,
              flags f,
              type* container)
            : base_type (s, e, f, container)
        {
        }

      public:
        name&
        operator= (C c)
        {
          base () = c;
          return *this;
        }

        name&
        operator= (C const* s)
        {
          base () = s;
          return *this;
        }

        name&
        operator= (primary_type const& str)
        {
          base () = str;
          return *this;
        }

        // Implicit copy assignment operator.
        //
      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, name<C> const& v)
      {
        token<C> const& r (v);
        return os << r;
      }


      // ncname: name
      //
      template <typename C>
      class ncname: public name<C>
      {
      protected:
        typedef name<C> base_type;
        typedef typename base_type::primary_type primary_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        ncname (C const* s)
            : base_type (s)
        {
        }

        ncname (C const* s, std::size_t n)
            : base_type (s, n)
        {
        }

        ncname (std::size_t n, C c)
            : base_type (n, c)
        {
        }

        ncname (primary_type const& str)
            : base_type (str)
        {
        }

        ncname (primary_type const& str,
                std::size_t pos,
                std::size_t n = primary_type::npos)
            : base_type (str, pos, n)
        {
        }

      public:
        ncname (ncname const& other, flags f = 0, type* container = 0)
            : base_type (other, f, container)
        {
        }

        virtual ncname*
        _clone (flags f = 0, type* container = 0) const
        {
          return new ncname (*this, f, container);
        }

      public:
        ncname (xml::dom::element<C> const& e, flags f, type* container)
            : base_type (e, f, container)
        {
        }

        ncname (xml::dom::attribute<C> const& a, flags f, type* container)
            : base_type (a, f, container)
        {
        }

        ncname (std::basic_string<C> const& s,
                xml::dom::element<C> const* e,
                flags f,
                type* container)
            : base_type (s, e, f, container)
        {
        }

      public:
        ncname&
        operator= (C c)
        {
          base () = c;
          return *this;
        }

        ncname&
        operator= (C const* s)
        {
          base () = s;
          return *this;
        }

        ncname&
        operator= (primary_type const& str)
        {
          base () = str;
          return *this;
        }

        // Implicit copy assignment operator.
        //

      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, ncname<C> const& v)
      {
        name<C> const& r (v);
        return os << r;
      }


      // language: token
      //
      template <typename C>
      class language: public token<C>
      {
      protected:
        typedef token<C> base_type;
        typedef typename base_type::primary_type primary_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        language (C const* s)
            : base_type (s)
        {
        }

        language (C const* s, std::size_t n)
            : base_type (s, n)
        {
        }

        language (std::size_t n, C c)
            : base_type (n, c)
        {
        }

        language (primary_type const& str)
            : base_type (str)
        {
        }

        language (primary_type const& str,
                  std::size_t pos,
                  std::size_t n = primary_type::npos)
            : base_type (str, pos, n)
        {
        }

      public:
        language (language const& other, flags f = 0, type* container = 0)
            : base_type (other, f, container)
        {
        }

        virtual language*
        _clone (flags f = 0, type* container = 0) const
        {
          return new language (*this, f, container);
        }

      public:
        language (xml::dom::element<C> const& e, flags f, type* container)
            : base_type (e, f, container)
        {
        }

        language (xml::dom::attribute<C> const& a, flags f, type* container)
            : base_type (a, f, container)
        {
        }

        language (std::basic_string<C> const& s,
                  xml::dom::element<C> const* e,
                  flags f,
                  type* container)
            : base_type (s, e, f, container)
        {
        }

      public:
        language&
        operator= (C c)
        {
          base () = c;
          return *this;
        }

        language&
        operator= (C const* s)
        {
          base () = s;
          return *this;
        }

        language&
        operator= (primary_type const& str)
        {
          base () = str;
          return *this;
        }

        // Implicit copy assignment operator.
        //
      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, language<C> const& v)
      {
        token<C> const& r (v);
        return os << r;
      }


      //
      //
      template <typename C>
      struct identity_impl: identity
      {
        identity_impl (ncname<C> const& id)
            : id_ (id)
        {
        }

        virtual bool
        before (identity const& y) const
        {
          return id_ < dynamic_cast<identity_impl const&> (y).id_;
        }

        virtual void
        throw_duplicate_id () const
        {
          throw duplicate_id<C> (id_);
        }

      private:
        ncname<C> const& id_;
      };


      // id: ncname
      //
      template <typename C>
      class id: public ncname<C>
      {
      protected:
        typedef ncname<C> base_type;
        typedef typename base_type::primary_type primary_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        using base_type::empty;

      public:
        ~id()
        {
          unregister_id ();
        }

      public:
        id (C const* s)
            : base_type (s), identity_ (*this)
        {
          register_id ();
        }

        id (C const* s, std::size_t n)
            : base_type (s, n), identity_ (*this)
        {
          register_id ();
        }

        id (std::size_t n, C c)
            : base_type (n, c), identity_ (*this)
        {
          register_id ();
        }

        id (primary_type const& str)
            : base_type (str), identity_ (*this)
        {
          register_id ();
        }

        id (primary_type const& str,
            std::size_t pos,
            std::size_t n = primary_type::npos)
            : base_type (str, pos, n), identity_ (*this)
        {
          register_id ();
        }

      public:
        id (id const& other, flags f = 0, type* container = 0)
            : base_type (other, f, container), identity_ (*this)
        {
          register_id ();
        }

        virtual id*
        _clone (flags f = 0, type* container = 0) const
        {
          return new id (*this, f, container);
        }

      public:
        id (xml::dom::element<C> const& e, flags f, type* container)
            : base_type (e, f, container), identity_ (*this)
        {
          register_id ();
        }

        id (xml::dom::attribute<C> const& a, flags f, type* container)
            : base_type (a, f, container), identity_ (*this)
        {
          register_id ();
        }

        id (std::basic_string<C> const& s,
            xml::dom::element<C> const* e,
            flags f,
            type* container)
            : base_type (s, e, f, container), identity_ (*this)
        {
          register_id ();
        }

      public:
        id&
        operator= (C c)
        {
          unregister_id ();
          base () = c;
          register_id ();

          return *this;
        }

        id&
        operator= (C const* s)
        {
          unregister_id ();
          base () = s;
          register_id ();

          return *this;
        }

        id&
        operator= (primary_type const& str)
        {
          unregister_id ();
          base () = str;
          register_id ();

          return *this;
        }

        id&
        operator= (id const& str)
        {
          unregister_id ();
          base () = str;
          register_id ();

          return *this;
        }

      public:
        using base_type::_container;

      private:
        void
        register_id ()
        {
          if (_container () != this && !empty ())
          {
            //std::cerr << "registering " << _container ()
            //          << " as '" << *this
            //          << "' on " << _container () << std::endl;
            _container ()->_register_id (identity_, _container ());
          }
        }

        void
        unregister_id ()
        {
          if (_container () != this && !empty ())
          {
            //std::cerr << "un-registering " << _container ()
            //          << " as '" << *this
            //          << "' on " << _container () << std::endl;
            _container ()->_unregister_id (identity_);
          }
        }

      private:
        identity_impl<C> identity_;
      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, id<C> const& v)
      {
        ncname<C> const& r (v);
        return os << r;
      }


      // idref: ncname
      //
      template <typename X, typename C>
      class idref: public ncname<C>
      {
      protected:
        typedef ncname<C> base_type;
        typedef typename base_type::primary_type primary_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        typedef X type;

      public:
        using base_type::empty;

      public:
        idref (C const* s)
            : base_type (s), identity_ (*this)
        {
        }

        idref (C const* s, std::size_t n)
            : base_type (s, n), identity_ (*this)
        {
        }

        idref (std::size_t n, C c)
            : base_type (n, c), identity_ (*this)
        {
        }

        idref (primary_type const& str)
            : base_type (str), identity_ (*this)
        {
        }

        idref (primary_type const& str,
               std::size_t pos,
               std::size_t n = primary_type::npos)
            : base_type (str, pos, n), identity_ (*this)
        {
        }

      public:
        idref (idref const& other, flags f = 0, tree::type* container = 0)
            : base_type (other, f, container), identity_ (*this)
        {
        }

        virtual idref*
        _clone (flags f = 0, tree::type* container = 0) const
        {
          return new idref (*this, f, container);
        }

      public:
        idref (xml::dom::element<C> const& e, flags f, tree::type* container)
            : base_type (e, f, container), identity_ (*this)
        {
        }

        idref (xml::dom::attribute<C> const& a,
               flags f,
               tree::type* container)
            : base_type (a, f , container), identity_ (*this)
        {
        }

        idref (std::basic_string<C> const& s,
               xml::dom::element<C> const* e,
               flags f,
               tree::type* container)
            : base_type (s, e, f, container), identity_ (*this)
        {
        }

      public:
        idref&
        operator= (C c)
        {
          base () = c;
          return *this;
        }

        idref&
        operator= (C const* s)
        {
          base () = s;
          return *this;
        }

        idref&
        operator= (primary_type const& str)
        {
          base () = str;
          return *this;
        }

        idref&
        operator= (idref const& str)
        {
          base () = str;
          return *this;
        }

      public:
        X const*
        operator-> () const
        {
          return get ();
        }

        X*
        operator-> ()
        {
          return get ();
        }

        X const&
        operator* () const
        {
          return *(get ());
        }

        X&
        operator* ()
        {
          return *(get ());
        }

        X const*
        get () const
        {
          return dynamic_cast<X const*> (get_ ());
        }

        X*
        get ()
        {
          return dynamic_cast<X*> (get_ ());
        }

        // Conversion to bool.
        //
        typedef void (idref::*bool_convertible)();

        operator bool_convertible () const
        {
          return get_ () ? &idref::true_ : 0;
        }

      public:
        using base_type::_root;
        using base_type::_container;

      private:
        tree::type const*
        get_ () const
        {
          if (!empty () && _container () != this)
          {
            return _root ()->_lookup_id (identity_);
          }
          else
            return 0;
        }

        tree::type*
        get_ ()
        {
          if (!empty () && _container () != this)
          {
            return _root ()->_lookup_id (identity_);
          }
          else
            return 0;
        }

      private:
        void
        true_ ()
        {
        }

      private:
        identity_impl<C> identity_;
      };

      template <typename X, typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, idref<X, C> const& v)
      {
        ncname<C> const& r (v);
        return os << r;
      }


      // idrefs: sequence<idref>
      //
      template <typename X, typename C>
      class idrefs: public simple_type, public sequence<idref<X, C> >

      {
        typedef sequence<idref<X, C> > base_type;

      public:
        idrefs ()
        {
        }

        idrefs (idrefs const& other, flags f = 0, type* container = 0)
            : simple_type (other, f, container),
              base_type (other, f, container)
        {
        }

        virtual idrefs*
        _clone (flags f = 0, type* container = 0) const
        {
          return new idrefs (*this, f, container);
        }

      public:
        idrefs (xml::dom::element<C> const& e, flags f, type* container)
            : simple_type (e, f, container), base_type (e, f, container)
        {
        }

        idrefs (xml::dom::attribute<C> const& a, flags f, type* container)
            : simple_type (a, f, container), base_type (a, f, container)
        {
        }

        idrefs (std::basic_string<C> const& s,
                xml::dom::element<C> const* e,
                flags f,
                type* container)
            : simple_type (s, e, f, container), base_type (s, e, f, container)
        {
        }
      };

      template <typename X, typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, idrefs<X, C> const& v)
      {
        sequence<idref<X, C> > const& r (v);
        return os << r;
      }

      // uri
      //
      template <typename C>
      class uri: public std::basic_string<C>, public simple_type
      {
      protected:
        typedef std::basic_string<C> primary_type;
        typedef std::basic_string<C> base_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        uri (C const* s)
            : base_type (s)
        {
        }

        uri (C const* s, std::size_t n)
            : base_type (s, n)
        {
        }

        uri (std::size_t n, C c)
            : base_type (n, c)
        {
        }

        uri (primary_type const& str)
            : base_type (str)
        {
        }

        uri (primary_type const& str,
             std::size_t pos,
             std::size_t n = primary_type::npos)
            : base_type (str, pos, n)
        {
        }

      public:
        uri (uri const& other, flags f = 0, type* container = 0)
            : base_type (other), simple_type (other, f, container)
        {
        }

        virtual uri*
        _clone (flags f = 0, type* container = 0) const
        {
          return new uri (*this, f, container);
        }

      public:
        uri (xml::dom::element<C> const& e, flags f, type* container)
            : base_type (e.value ()), simple_type (e, f, container)
        {
        }

        uri (xml::dom::attribute<C> const& a, flags f, type* container)
            : base_type (a.value ()), simple_type (a, f, container)
        {
        }

        uri (std::basic_string<C> const& s,
             xml::dom::element<C> const* e,
             flags f,
             type* container)
            : base_type (s), simple_type (s, e, f, container)
        {
        }

      public:
        uri&
        operator= (C c)
        {
          base () = c;
          return *this;
        }

        uri&
        operator= (C const* s)
        {
          base () = s;
          return *this;
        }

        uri&
        operator= (primary_type const& str)
        {
          base () = str;
          return *this;
        }

        // Implicit copy assignment operator.
        //

      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, uri<C> const& v)
      {
        std::basic_string<C> const& r (v);
        return os << r;
      }


      // qname
      //
      template <typename C>
      class qname: public simple_type
      {
      public:
        qname (uri<C> const& ns, ncname<C> const& name)
            : ns_ (ns), name_ (name)
        {
        }

      public:
        qname (qname const& other, flags f = 0, type* container = 0)
            : simple_type (other, f, container),
              ns_ (other.ns_),
              name_ (other.name_)
        {
          // Note that ns_ and name_ have no DOM association.
          //
        }

        virtual qname*
        _clone (flags f = 0, type* container = 0) const
        {
          return new qname (*this, f, container);
        }

      public:
        qname (xml::dom::element<C> const& e, flags f, type* container)
            : simple_type (e, f, container),
              ns_ (xml::dom::ns_name (e, e.value ())),
              name_ (xml::uq_name (e.value ()))
        {
        }

        qname (xml::dom::attribute<C> const& a, flags f, type* container)
            : simple_type (a, f, container),
              ns_ (xml::dom::ns_name (a.element (), a.value ())),
              name_ (xml::uq_name (a.value ()))
        {
        }

        qname (std::basic_string<C> const& s,
               xml::dom::element<C> const* e,
               flags f,
               type* container)
            : simple_type (s, e, f, container),
              ns_ (resolve (s, e)),
              name_ (xml::uq_name (s))
        {
        }

      public:
        uri<C> const&
        namespace_ () const
        {
          return ns_;
        }

        ncname<C> const&
        name () const
        {
          return name_;
        }

      private:
        static uri<C>
        resolve (std::basic_string<C> const& s, xml::dom::element<C> const* e)
        {
          if (e)
            return uri<C> (xml::dom::ns_name (*e, s));
          else
            throw no_prefix_mapping<C> (xml::prefix (s));
        }

      private:
        uri<C> ns_;
        ncname<C> name_;
      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, qname<C> const& n)
      {
        return os << n.namespace_ () << C ('#') << n.name ();
      }


      // base64_binary
      //
      template <typename C>
      class base64_binary: public simple_type, public buffer<C>
      {
      public:
        typedef typename buffer<C>::size_t size_t;

        using buffer<C>::data;
        using buffer<C>::size;

      public:
        base64_binary (size_t size = 0);
        base64_binary (size_t size, size_t capacity);
        base64_binary (void const* data, size_t size);
        base64_binary (void const* data, size_t size, size_t capacity);

        // If the assume_ownership argument is true, the buffer will
        // assume the ownership of data and will release the memory
        // by calling operator delete ().
        //
        base64_binary (void* data,
                       size_t size,
                       size_t capacity,
                       bool assume_ownership);

      public:
        base64_binary (base64_binary const& other,
                       flags f = 0,
                       type* container = 0)
            : simple_type (other, f, container), buffer<C> (other)
        {
        }

        virtual base64_binary*
        _clone (flags f = 0, type* container = 0) const
        {
          return new base64_binary (*this, f, container);
        }

      public:
        base64_binary (xml::dom::element<C> const& e,
                       flags f,
                       type* container)
            : simple_type (e, f, container)
        {
          decode (e.dom_element ()->getTextContent ());
        }

        base64_binary (xml::dom::attribute<C> const& a,
                       flags f,
                       type* container)
            : simple_type (a, f, container)
        {
          decode (a.dom_attribute ()->getValue ());
        }

        base64_binary (std::basic_string<C> const& s,
                       xml::dom::element<C> const* e,
                       flags f,
                       type* container)
            : simple_type (s, e, f, container)
        {
          decode (xml::string (s).c_str ());
        }

      public:
        std::basic_string<C>
        encode () const;

      public:
        // Implicit copy assignment operator.
        //

      private:
        void
        decode (XMLCh const*);
      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, base64_binary<C> const& v)
      {
        return os << v.encode ();
      }


      // hex_binary
      //
      template <typename C>
      class hex_binary: public simple_type, public buffer<C>
      {
      public:
        typedef typename buffer<C>::size_t size_t;

        using buffer<C>::data;
        using buffer<C>::size;

      public:
        hex_binary (size_t size = 0);
        hex_binary (size_t size, size_t capacity);
        hex_binary (void const* data, size_t size);
        hex_binary (void const* data, size_t size, size_t capacity);

        // If the assume_ownership argument is true, the buffer will
        // assume the ownership of data and will release the memory
        // by calling operator delete ().
        //
        hex_binary (void* data,
                    size_t size,
                    size_t capacity,
                    bool assume_ownership);

      public:
        hex_binary (hex_binary const& other, flags f = 0, type* container = 0)
            : simple_type (other, f, container), buffer<C> (other)
        {
        }

        virtual hex_binary*
        _clone (flags f = 0, type* container = 0) const
        {
          return new hex_binary (*this, f, container);
        }

      public:
        hex_binary (xml::dom::element<C> const& e, flags f, type* container)
            : simple_type (e, f, container)
        {
          decode (e.dom_element ()->getTextContent ());
        }

        hex_binary (xml::dom::attribute<C> const& a, flags f, type* container)
            : simple_type (a, f, container)
        {
          decode (a.dom_attribute ()->getValue ());
        }

        hex_binary (std::basic_string<C> const& s,
                    xml::dom::element<C> const* e,
                    flags f,
                    type* container)
            : simple_type (s, e, f, container)
        {
          decode (xml::string (s).c_str ());
        }

      public:
        std::basic_string<C>
        encode () const;

      public:
        // Implicit copy assignment operator.
        //

      private:
        void
        decode (XMLCh const*);
      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, hex_binary<C> const& v)
      {
        return os << v.encode ();
      }


      // date
      //
      template <typename C>
      class date: public std::basic_string<C>, public simple_type
      {
      protected:
        typedef std::basic_string<C> primary_type;
        typedef std::basic_string<C> base_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        date (C const* s)
            : base_type (s)
        {
        }

        date (C const* s, std::size_t n)
            : base_type (s, n)
        {
        }

        date (std::size_t n, C c)
            : base_type (n, c)
        {
        }

        date (primary_type const& str)
            : base_type (str)
        {
        }

        date (primary_type const& str,
              std::size_t pos,
              std::size_t n = primary_type::npos)
            : base_type (str, pos, n)
        {
        }

      public:
        date (date const& other, flags f = 0, type* container = 0)
            : base_type (other), simple_type (other, f, container)
        {
        }

        virtual date*
        _clone (flags f = 0, type* container = 0) const
        {
          return new date (*this, f, container);
        }

      public:
        date (xml::dom::element<C> const& e, flags f, type* container)
            : base_type (e.value ()), simple_type (e, f, container)
        {
        }

        date (xml::dom::attribute<C> const& a, flags f, type* container)
            : base_type (a.value ()), simple_type (a, f, container)
        {
        }

        date (std::basic_string<C> const& s,
              xml::dom::element<C> const* e,
              flags f,
              type* container)
            : base_type (s), simple_type (s, e, f, container)
        {
        }

      public:
        date&
        operator= (C c)
        {
          base () = c;
          return *this;
        }

        date&
        operator= (C const* s)
        {
          base () = s;
          return *this;
        }

        date&
        operator= (primary_type const& str)
        {
          base () = str;
          return *this;
        }

        // Implicit copy assignment operator.
        //
      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, date<C> const& v)
      {
        std::basic_string<C> const& r (v);
        return os << r;
      }


      // date_time
      //
      template <typename C>
      class date_time: public std::basic_string<C>, public simple_type
      {
      protected:
        typedef std::basic_string<C> primary_type;
        typedef std::basic_string<C> base_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        date_time (C const* s)
            : base_type (s)
        {
        }

        date_time (C const* s, std::size_t n)
            : base_type (s, n)
        {
        }

        date_time (std::size_t n, C c)
            : base_type (n, c)
        {
        }

        date_time (primary_type const& str)
            : base_type (str)
        {
        }

        date_time (primary_type const& str,
                   std::size_t pos,
                   std::size_t n = primary_type::npos)
            : base_type (str, pos, n)
        {
        }

      public:
        date_time (date_time const& other, flags f = 0, type* container = 0)
            : base_type (other), simple_type (other, f, container)
        {
        }

        virtual date_time*
        _clone (flags f = 0, type* container = 0) const
        {
          return new date_time (*this, f, container);
        }

      public:
        date_time (xml::dom::element<C> const& e, flags f, type* container)
            : base_type (e.value ()), simple_type (e, f, container)
        {
        }

        date_time (xml::dom::attribute<C> const& a, flags f, type* container)
            : base_type (a.value ()), simple_type (a, f, container)
        {
        }

        date_time (std::basic_string<C> const& s,
                   xml::dom::element<C> const* e,
                   flags f,
                   type* container)
            : base_type (s), simple_type (s, e, f, container)
        {
        }

      public:
        date_time&
        operator= (C c)
        {
          base () = c;
          return *this;
        }

        date_time&
        operator= (C const* s)
        {
          base () = s;
          return *this;
        }

        date_time&
        operator= (primary_type const& str)
        {
          base () = str;
          return *this;
        }

        // Implicit copy assignment operator.
        //

      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, date_time<C> const& v)
      {
        std::basic_string<C> const& r (v);
        return os << r;
      }


      // duration
      //
      template <typename C>
      class duration: public std::basic_string<C>, public simple_type
      {
      protected:
        typedef std::basic_string<C> primary_type;
        typedef std::basic_string<C> base_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        duration (C const* s)
            : base_type (s)
        {
        }

        duration (C const* s, std::size_t n)
            : base_type (s, n)
        {
        }

        duration (std::size_t n, C c)
            : base_type (n, c)
        {
        }

        duration (primary_type const& str)
            : base_type (str)
        {
        }

        duration (primary_type const& str,
                  std::size_t pos,
                  std::size_t n = primary_type::npos)
            : base_type (str, pos, n)
        {
        }

      public:
        duration (duration const& other, flags f = 0, type* container = 0)
            : base_type (other), simple_type (other, f, container)
        {
        }

        virtual duration*
        _clone (flags f = 0, type* container = 0) const
        {
          return new duration (*this, f, container);
        }

      public:
        duration (xml::dom::element<C> const& e, flags f, type* container)
            : base_type (e.value ()), simple_type (e, f, container)
        {
        }

        duration (xml::dom::attribute<C> const& a, flags f, type* container)
            : base_type (a.value ()), simple_type (a, f, container)
        {
        }

        duration (std::basic_string<C> const& s,
                  xml::dom::element<C> const* e,
                  flags f,
                  type* container)
            : base_type (s), simple_type (s, e, f, container)
        {
        }

      public:
        duration&
        operator= (C c)
        {
          base () = c;
          return *this;
        }

        duration&
        operator= (C const* s)
        {
          base () = s;
          return *this;
        }

        duration&
        operator= (primary_type const& str)
        {
          base () = str;
          return *this;
        }

        // Implicit copy assignment operator.
        //

      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, duration<C> const& v)
      {
        std::basic_string<C> const& r (v);
        return os << r;
      }


      // day
      //
      template <typename C>
      class day: public std::basic_string<C>, public simple_type
      {
      protected:
        typedef std::basic_string<C> primary_type;
        typedef std::basic_string<C> base_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        day (C const* s)
            : base_type (s)
        {
        }

        day (C const* s, std::size_t n)
            : base_type (s, n)
        {
        }

        day (std::size_t n, C c)
            : base_type (n, c)
        {
        }

        day (primary_type const& str)
            : base_type (str)
        {
        }

        day (primary_type const& str,
             std::size_t pos,
             std::size_t n = primary_type::npos)
            : base_type (str, pos, n)
        {
        }

      public:
        day (day const& other, flags f = 0, type* container = 0)
            : base_type (other), simple_type (other, f, container)
        {
        }

        virtual day*
        _clone (flags f = 0, type* container = 0) const
        {
          return new day (*this, f, container);
        }

      public:
        day (xml::dom::element<C> const& e, flags f, type* container)
            : base_type (e.value ()), simple_type (e, f, container)
        {
        }

        day (xml::dom::attribute<C> const& a, flags f, type* container)
            : base_type (a.value ()), simple_type (a, f, container)
        {
        }

        day (std::basic_string<C> const& s,
             xml::dom::element<C> const* e,
             flags f,
             type* container)
            : base_type (s), simple_type (s, e, f, container)
        {
        }

      public:
        day&
        operator= (C c)
        {
          base () = c;
          return *this;
        }

        day&
        operator= (C const* s)
        {
          base () = s;
          return *this;
        }

        day&
        operator= (primary_type const& str)
        {
          base () = str;
          return *this;
        }

        // Implicit copy assignment operator.
        //

      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, day<C> const& v)
      {
        std::basic_string<C> const& r (v);
        return os << r;
      }


      // month
      //
      template <typename C>
      class month: public std::basic_string<C>, public simple_type
      {
      protected:
        typedef std::basic_string<C> primary_type;
        typedef std::basic_string<C> base_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        month (C const* s)
            : base_type (s)
        {
        }

        month (C const* s, std::size_t n)
            : base_type (s, n)
        {
        }

        month (std::size_t n, C c)
            : base_type (n, c)
        {
        }

        month (primary_type const& str)
            : base_type (str)
        {
        }

        month (primary_type const& str,
               std::size_t pos,
               std::size_t n = primary_type::npos)
            : base_type (str, pos, n)
        {
        }

      public:
        month (month const& other, flags f = 0, type* container = 0)
            : base_type (other), simple_type (other, f, container)
        {
        }

        virtual month*
        _clone (flags f = 0, type* container = 0) const
        {
          return new month (*this, f, container);
        }

      public:
        month (xml::dom::element<C> const& e, flags f, type* container)
            : base_type (e.value ()), simple_type (e, f, container)
        {
        }

        month (xml::dom::attribute<C> const& a, flags f, type* container)
            : base_type (a.value ()), simple_type (a, f, container)
        {
        }

        month (std::basic_string<C> const& s,
               xml::dom::element<C> const* e,
               flags f,
               type* container)
            : base_type (s), simple_type (s, e, f, container)
        {
        }

      public:
        month&
        operator= (C c)
        {
          base () = c;
          return *this;
        }

        month&
        operator= (C const* s)
        {
          base () = s;
          return *this;
        }

        month&
        operator= (primary_type const& str)
        {
          base () = str;
          return *this;
        }

        // Implicit copy assignment operator.
        //

      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, month<C> const& v)
      {
        std::basic_string<C> const& r (v);
        return os << r;
      }


      // month_day
      //
      template <typename C>
      class month_day: public std::basic_string<C>, public simple_type
      {
      protected:
        typedef std::basic_string<C> primary_type;
        typedef std::basic_string<C> base_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        month_day (C const* s)
            : base_type (s)
        {
        }

        month_day (C const* s, std::size_t n)
            : base_type (s, n)
        {
        }

        month_day (std::size_t n, C c)
            : base_type (n, c)
        {
        }

        month_day (primary_type const& str)
            : base_type (str)
        {
        }

        month_day (primary_type const& str,
                   std::size_t pos,
                   std::size_t n = primary_type::npos)
            : base_type (str, pos, n)
        {
        }

      public:
        month_day (month_day const& other, flags f = 0, type* container = 0)
            : base_type (other), simple_type (other, f, container)
        {
        }

        virtual month_day*
        _clone (flags f = 0, type* container = 0) const
        {
          return new month_day (*this, f, container);
        }

      public:
        month_day (xml::dom::element<C> const& e, flags f, type* container)
            : base_type (e.value ()), simple_type (e, f, container)
        {
        }

        month_day (xml::dom::attribute<C> const& a, flags f, type* container)
            : base_type (a.value ()), simple_type (a, f, container)
        {
        }

        month_day (std::basic_string<C> const& s,
                   xml::dom::element<C> const* e,
                   flags f,
                   type* container)
            : base_type (s), simple_type (s, e, f, container)
        {
        }

      public:
        month_day&
        operator= (C c)
        {
          base () = c;
          return *this;
        }

        month_day&
        operator= (C const* s)
        {
          base () = s;
          return *this;
        }

        month_day&
        operator= (primary_type const& str)
        {
          base () = str;
          return *this;
        }

        // Implicit copy assignment operator.
        //

      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, month_day<C> const& v)
      {
        std::basic_string<C> const& r (v);
        return os << r;
      }


      // year
      //
      template <typename C>
      class year: public std::basic_string<C>, public simple_type
      {
      protected:
        typedef std::basic_string<C> primary_type;
        typedef std::basic_string<C> base_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        year (C const* s)
            : base_type (s)
        {
        }

        year (C const* s, std::size_t n)
            : base_type (s, n)
        {
        }

        year (std::size_t n, C c)
            : base_type (n, c)
        {
        }

        year (primary_type const& str)
            : base_type (str)
        {
        }

        year (primary_type const& str,
              std::size_t pos,
              std::size_t n = primary_type::npos)
            : base_type (str, pos, n)
        {
        }

      public:
        year (year const& other, flags f = 0, type* container = 0)
            : base_type (other), simple_type (other, f, container)
        {
        }

        virtual year*
        _clone (flags f = 0, type* container = 0) const
        {
          return new year (*this, f, container);
        }

      public:
        year (xml::dom::element<C> const& e, flags f, type* container)
            : base_type (e.value ()), simple_type (e, f, container)
        {
        }

        year (xml::dom::attribute<C> const& a, flags f, type* container)
            : base_type (a.value ()), simple_type (a, f, container)
        {
        }

        year (std::basic_string<C> const& s,
              xml::dom::element<C> const* e,
              flags f,
              type* container)
            : base_type (s), simple_type (s, e, f, container)
        {
        }

      public:
        year&
        operator= (C c)
        {
          base () = c;
          return *this;
        }

        year&
        operator= (C const* s)
        {
          base () = s;
          return *this;
        }

        year&
        operator= (primary_type const& str)
        {
          base () = str;
          return *this;
        }

        // Implicit copy assignment operator.
        //

      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, year<C> const& v)
      {
        std::basic_string<C> const& r (v);
        return os << r;
      }


      // year_month
      //
      template <typename C>
      class year_month: public std::basic_string<C>, public simple_type
      {
      protected:
        typedef std::basic_string<C> primary_type;
        typedef std::basic_string<C> base_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        year_month (C const* s)
            : base_type (s)
        {
        }

        year_month (C const* s, std::size_t n)
            : base_type (s, n)
        {
        }

        year_month (std::size_t n, C c)
            : base_type (n, c)
        {
        }

        year_month (primary_type const& str)
            : base_type (str)
        {
        }

        year_month (primary_type const& str,
                    std::size_t pos,
                    std::size_t n = primary_type::npos)
            : base_type (str, pos, n)
        {
        }

      public:
        year_month (year_month const& other, flags f = 0, type* container = 0)
            : base_type (other), simple_type (other, f, container)
        {
        }

        virtual year_month*
        _clone (flags f = 0, type* container = 0) const
        {
          return new year_month (*this, f, container);
        }

      public:
        year_month (xml::dom::element<C> const& e, flags f, type* container)
            : base_type (e.value ()), simple_type (e, f, container)
        {
        }

        year_month (xml::dom::attribute<C> const& a, flags f, type* container)
            : base_type (a.value ()), simple_type (a, f, container)
        {
        }

        year_month (std::basic_string<C> const& s,
                    xml::dom::element<C> const* e,
                    flags f,
                    type* container)
            : base_type (s), simple_type (s, e, f, container)
        {
        }

      public:
        year_month&
        operator= (C c)
        {
          base () = c;
          return *this;
        }

        year_month&
        operator= (C const* s)
        {
          base () = s;
          return *this;
        }

        year_month&
        operator= (primary_type const& str)
        {
          base () = str;
          return *this;
        }

        // Implicit copy assignment operator.
        //

      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, year_month<C> const& v)
      {
        std::basic_string<C> const& r (v);
        return os << r;
      }


      // time
      //
      template <typename C>
      class time: public std::basic_string<C>, public simple_type
      {
      protected:
        typedef std::basic_string<C> primary_type;
        typedef std::basic_string<C> base_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        time (C const* s)
            : base_type (s)
        {
        }

        time (C const* s, std::size_t n)
            : base_type (s, n)
        {
        }

        time (std::size_t n, C c)
            : base_type (n, c)
        {
        }

        time (primary_type const& str)
            : base_type (str)
        {
        }

        time (primary_type const& str,
              std::size_t pos,
              std::size_t n = primary_type::npos)
            : base_type (str, pos, n)
        {
        }

      public:
        time (time const& other, flags f = 0, type* container = 0)
            : base_type (other), simple_type (other, f, container)
        {
        }

        virtual time*
        _clone (flags f = 0, type* container = 0) const
        {
          return new time (*this, f, container);
        }

      public:
        time (xml::dom::element<C> const& e, flags f, type* container)
            : base_type (e.value ()), simple_type (e, f, container)
        {
        }

        time (xml::dom::attribute<C> const& a, flags f, type* container)
            : base_type (a.value ()), simple_type (a, f, container)
        {
        }

        time (std::basic_string<C> const& s,
              xml::dom::element<C> const* e,
              flags f,
              type* container)
            : base_type (s), simple_type (s, e, f, container)
        {
        }

      public:
        time&
        operator= (C c)
        {
          base () = c;
          return *this;
        }

        time&
        operator= (C const* s)
        {
          base () = s;
          return *this;
        }

        time&
        operator= (primary_type const& str)
        {
          base () = str;
          return *this;
        }

        // Implicit copy assignment operator.
        //

      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, time<C> const& v)
      {
        std::basic_string<C> const& r (v);
        return os << r;
      }


      // entity: ncname
      //
      template <typename C>
      class entity: public ncname<C>
      {
      protected:
        typedef ncname<C> base_type;
        typedef typename base_type::primary_type primary_type;

        base_type&
        base ()
        {
          return *this;
        }

      public:
        entity (C const* s)
            : base_type (s)
        {
        }

        entity (C const* s, std::size_t n)
            : base_type (s, n)
        {
        }

        entity (std::size_t n, C c)
            : base_type (n, c)
        {
        }

        entity (primary_type const& str)
            : base_type (str)
        {
        }

        entity (primary_type const& str,
                std::size_t pos,
                std::size_t n = primary_type::npos)
            : base_type (str, pos, n)
        {
        }

      public:
        entity (entity const& other, flags f = 0, type* container = 0)
            : base_type (other, f, container)
        {
        }

        virtual entity*
        _clone (flags f = 0, type* container = 0) const
        {
          return new entity (*this, f, container);
        }

      public:
        entity (xml::dom::element<C> const& e, flags f, type* container)
            : base_type (e, f, container)
        {
        }

        entity (xml::dom::attribute<C> const& a, flags f, type* container)
            : base_type (a, f, container)
        {
        }

        entity (std::basic_string<C> const& s,
                xml::dom::element<C> const* e,
                flags f,
                type* container)
            : base_type (s, e, f, container)
        {
        }

      public:
        entity&
        operator= (C c)
        {
          base () = c;
          return *this;
        }

        entity&
        operator= (C const* s)
        {
          base () = s;
          return *this;
        }

        entity&
        operator= (primary_type const& str)
        {
          base () = str;
          return *this;
        }

        // Implicit copy assignment operator.
        //

      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, entity<C> const& v)
      {
        ncname<C> const& r (v);
        return os << r;
      }


      // entities: sequence<entity>
      //
      template <typename C>
      class entities: public simple_type, public sequence<entity<C> >
      {
        typedef sequence<entity<C> > base_type;

      public:
        entities ()
        {
        }

        entities (entities const& other, flags f = 0, type* container = 0)
            : simple_type (other, f, container),
              base_type (other, f, container)
        {
        }

        virtual entities*
        _clone (flags f = 0, type* container = 0) const
        {
          return new entities (*this, f, container);
        }

      public:
        entities (xml::dom::element<C> const& e, flags f, type* container)
            : simple_type (e, f, container), base_type (e, f, container)
        {
        }

        entities (xml::dom::attribute<C> const& a, flags f, type* container)
            : simple_type (a, f, container), base_type (a, f, container)
        {
        }

        entities (std::basic_string<C> const& s,
                  xml::dom::element<C> const* e,
                  flags f,
                  type* container)
            : simple_type (s, e, f, container), base_type (s, e, f, container)
        {
        }
      };

      template <typename C>
      inline std::basic_ostream<C>&
      operator<< (std::basic_ostream<C>& os, entities<C> const& v)
      {
        sequence<entity<C> > const& r (v);
        return os << r;
      }
    }
  }
}

#include <xsd/cxx/tree/types.txx>

#endif  // XSD_CXX_TREE_TYPES_HXX
