COMPASSi/trunk/code/inc/DataManager/XmlSerialization/xsd/cxx/tree/containers-wildcard.hxx

1338 lines
30 KiB
C++

// file : xsd/cxx/tree/containers-wildcard.hxx
// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
#ifndef XSD_CXX_TREE_CONTAINERS_WILDCARD_HXX
#define XSD_CXX_TREE_CONTAINERS_WILDCARD_HXX
#include <set>
#include <string>
#include <xercesc/dom/DOMAttr.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xsd/cxx/xml/string.hxx>
#include <xsd/cxx/tree/iterator-adapter.hxx>
namespace xsd
{
namespace cxx
{
namespace tree
{
// one (for internal use only)
//
class element_one
{
public:
typedef xercesc::DOMElement value_type;
~element_one ()
{
if (x_)
x_->release ();
}
explicit
element_one (xercesc::DOMDocument& doc)
: x_ (0), doc_ (doc)
{
}
element_one (const xercesc::DOMElement& x, xercesc::DOMDocument& doc)
: x_ (0), doc_ (doc)
{
set (x);
}
element_one (const element_one& x, xercesc::DOMDocument& doc)
: x_ (0), doc_ (doc)
{
if (x.present ())
set (x.get ());
}
element_one&
operator= (const element_one& x)
{
if (this == &x)
return *this;
if (x.present ())
set (x.get ());
else if (x_)
{
x_->release ();
x_ = 0;
}
return *this;
}
public:
const xercesc::DOMElement&
get () const
{
return *x_;
}
xercesc::DOMElement&
get ()
{
return *x_;
}
void
set (const xercesc::DOMElement& x)
{
using xercesc::DOMElement;
DOMElement* r (
static_cast<DOMElement*> (
doc_.importNode (const_cast<DOMElement*> (&x), true)));
if (x_)
x_->release ();
x_ = r;
}
void
set (xercesc::DOMElement* x)
{
assert (x->getOwnerDocument () == &doc_);
if (x_)
x_->release ();
x_ = x;
}
bool
present () const
{
return x_ != 0;
}
protected:
xercesc::DOMElement* x_;
xercesc::DOMDocument& doc_;
};
//
//
class element_optional
{
public:
typedef xercesc::DOMElement value_type;
~element_optional ()
{
if (x_)
x_->release ();
}
explicit
element_optional (xercesc::DOMDocument& doc)
: x_ (0), doc_ (doc)
{
}
element_optional (const xercesc::DOMElement& x,
xercesc::DOMDocument& doc)
: x_ (0), doc_ (doc)
{
set (x);
}
element_optional (xercesc::DOMElement* x, xercesc::DOMDocument& doc)
: x_ (0), doc_ (doc)
{
set (x);
}
element_optional (const element_optional& x,
xercesc::DOMDocument& doc)
: x_ (0), doc_ (doc)
{
if (x)
set (*x);
}
element_optional&
operator= (const xercesc::DOMElement& x)
{
if (x_ == &x)
return *this;
set (x);
return *this;
}
element_optional&
operator= (const element_optional& x)
{
if (this == &x)
return *this;
if (x)
set (*x);
else
reset ();
return *this;
}
// Pointer-like interface.
//
public:
const xercesc::DOMElement*
operator-> () const
{
return x_;
}
xercesc::DOMElement*
operator-> ()
{
return x_;
}
const xercesc::DOMElement&
operator* () const
{
return *x_;
}
xercesc::DOMElement&
operator* ()
{
return *x_;
}
typedef void (element_optional::*bool_convertible) ();
operator bool_convertible () const
{
return x_ != 0 ? &element_optional::true_ : 0;
}
// Get/set interface.
//
public:
bool
present () const
{
return x_ != 0;
}
const xercesc::DOMElement&
get () const
{
return *x_;
}
xercesc::DOMElement&
get ()
{
return *x_;
}
void
set (const xercesc::DOMElement& x)
{
using xercesc::DOMElement;
DOMElement* r (
static_cast<DOMElement*> (
doc_.importNode (const_cast<DOMElement*> (&x), true)));
if (x_)
x_->release ();
x_ = r;
}
void
set (xercesc::DOMElement* x)
{
assert (x->getOwnerDocument () == &doc_);
if (x_)
x_->release ();
x_ = x;
}
void
reset ()
{
if (x_)
x_->release ();
x_ = 0;
}
private:
void
true_ ()
{
}
private:
xercesc::DOMElement* x_;
xercesc::DOMDocument& doc_;
};
// Comparison operators.
//
inline bool
operator== (const element_optional& a, const element_optional& b)
{
return !a || !b
? a.present () == b.present ()
: a->isEqualNode (&b.get ());
}
inline bool
operator!= (const element_optional& a, const element_optional& b)
{
return !(a == b);
}
//
//
class element_sequence
{
protected:
// This is a dangerously destructive automatic pointer. We are going
// to use it in a controlled environment to save us a lot of coding.
//
struct ptr
{
~ptr ()
{
if (x_)
x_->release ();
}
explicit
ptr (xercesc::DOMElement* x = 0)
: x_ (x)
{
}
ptr (const ptr& y)
: x_ (y.x_)
{
// Yes, hostile takeover.
//
y.x_ = 0;
}
ptr&
operator= (const ptr& y)
{
if (this != &y)
{
// Yes, hostile takeover.
//
if (x_)
x_->release ();
x_ = y.x_;
y.x_ = 0;
}
return *this;
}
public:
xercesc::DOMElement&
operator* () const
{
return *x_;
}
xercesc::DOMElement*
get () const
{
return x_;
}
private:
mutable xercesc::DOMElement* x_;
};
typedef std::vector<ptr> base_sequence;
typedef base_sequence::iterator base_iterator;
typedef base_sequence::const_iterator base_const_iterator;
public:
typedef xercesc::DOMElement value_type;
typedef xercesc::DOMElement* pointer;
typedef const xercesc::DOMElement* const_pointer;
typedef xercesc::DOMElement& reference;
typedef const xercesc::DOMElement& const_reference;
typedef
iterator_adapter<base_sequence::iterator, xercesc::DOMElement>
iterator;
typedef
iterator_adapter<base_sequence::const_iterator,
const xercesc::DOMElement>
const_iterator;
typedef
iterator_adapter<base_sequence::reverse_iterator, xercesc::DOMElement>
reverse_iterator;
typedef
iterator_adapter<base_sequence::const_reverse_iterator,
const xercesc::DOMElement>
const_reverse_iterator;
typedef base_sequence::size_type size_type;
typedef base_sequence::difference_type difference_type;
typedef base_sequence::allocator_type allocator_type;
public:
explicit
element_sequence (xercesc::DOMDocument& doc)
: doc_ (doc)
{
}
// DOMElement cannot be default-constructed.
//
// explicit
// element_sequence (size_type n);
element_sequence (size_type n,
const xercesc::DOMElement& x,
xercesc::DOMDocument& doc)
: doc_ (doc)
{
assign (n, x);
}
template <typename I>
element_sequence (const I& begin, const I& end,
xercesc::DOMDocument& doc)
: doc_ (doc)
{
assign (begin, end);
}
element_sequence (const element_sequence& v,
xercesc::DOMDocument& doc)
: doc_ (doc)
{
v_.reserve (v.v_.size ());
for (base_const_iterator i (v.v_.begin ()), e (v.v_.end ());
i != e; ++i)
{
ptr p (static_cast<xercesc::DOMElement*> (
doc_.importNode (i->get (), true)));
v_.push_back (p);
}
}
element_sequence&
operator= (const element_sequence& v)
{
if (this == &v)
return *this;
v_.assign (v.v_.size (), ptr ());
base_iterator di (v_.begin ()), de (v_.end ());
base_const_iterator si (v.v_.begin ()), se (v.v_.end ());
for (; si != se && di != de; ++si, ++di)
{
ptr p (static_cast<xercesc::DOMElement*> (
doc_.importNode (si->get (), true)));
*di = p;
}
return *this;
}
public:
void
assign (size_type n, const xercesc::DOMElement& x)
{
v_.assign (n, ptr ());
for (base_iterator i (v_.begin ()), e (v_.end ()); i != e; ++i)
{
ptr p (static_cast<xercesc::DOMElement*> (
doc_.importNode (
const_cast<xercesc::DOMElement*> (&x), true)));
*i = p;
}
}
template <typename I>
void
assign (const I& begin, const I& end)
{
// This is not the fastest way to do it.
//
v_.clear ();
for (I i (begin); i != end; ++i)
{
ptr p (static_cast<xercesc::DOMElement*> (
doc_.importNode (
const_cast<xercesc::DOMElement*> (&(*i)), true)));
v_.push_back (p);
}
}
public:
// This version of resize can only be used to shrink the
// sequence because DOMElement cannot be default-constructed.
//
void
resize (size_type n)
{
assert (n <= v_.size ());
v_.resize (n, ptr ());
}
void
resize (size_type n, const xercesc::DOMElement& x)
{
size_type old (v_.size ());
v_.resize (n, ptr ());
if (old < n)
{
for (base_iterator i (v_.begin () + old), e (v_.end ());
i != e; ++i)
{
ptr p (static_cast<xercesc::DOMElement*> (
doc_.importNode (
const_cast<xercesc::DOMElement*> (&x), true)));
*i = p;
}
}
}
public:
size_type
size () const
{
return v_.size ();
}
size_type
max_size () const
{
return v_.max_size ();
}
size_type
capacity () const
{
return v_.capacity ();
}
bool
empty () const
{
return v_.empty ();
}
void
reserve (size_type n)
{
v_.reserve (n);
}
void
clear ()
{
v_.clear ();
}
public:
const_iterator
begin () const
{
return const_iterator (v_.begin ());
}
const_iterator
end () const
{
return const_iterator (v_.end ());
}
iterator
begin ()
{
return iterator (v_.begin ());
}
iterator
end ()
{
return iterator (v_.end ());
}
// reverse
//
const_reverse_iterator
rbegin () const
{
return const_reverse_iterator (v_.rbegin ());
}
const_reverse_iterator
rend () const
{
return const_reverse_iterator (v_.rend ());
}
reverse_iterator
rbegin ()
{
return reverse_iterator (v_.rbegin ());
}
reverse_iterator
rend ()
{
return reverse_iterator (v_.rend ());
}
public:
xercesc::DOMElement&
operator[] (size_type n)
{
return *(v_[n]);
}
const xercesc::DOMElement&
operator[] (size_type n) const
{
return *(v_[n]);
}
xercesc::DOMElement&
at (size_type n)
{
return *(v_.at (n));
}
const xercesc::DOMElement&
at (size_type n) const
{
return *(v_.at (n));
}
xercesc::DOMElement&
front ()
{
return *(v_.front ());
}
const xercesc::DOMElement&
front () const
{
return *(v_.front ());
}
xercesc::DOMElement&
back ()
{
return *(v_.back ());
}
const xercesc::DOMElement&
back () const
{
return *(v_.back ());
}
public:
// Makes a deep copy.
//
void
push_back (const xercesc::DOMElement& x)
{
ptr p (static_cast<xercesc::DOMElement*> (
doc_.importNode (
const_cast<xercesc::DOMElement*> (&x), true)));
v_.push_back (p);
}
// Assumes ownership.
//
void
push_back (xercesc::DOMElement* x)
{
assert (x->getOwnerDocument () == &doc_);
v_.push_back (ptr (x));
}
void
pop_back ()
{
v_.pop_back ();
}
// Makes a deep copy.
//
iterator
insert (iterator position, const xercesc::DOMElement& x)
{
ptr p (static_cast<xercesc::DOMElement*> (
doc_.importNode (
const_cast<xercesc::DOMElement*> (&x), true)));
return iterator (v_.insert (position.base (), p));
}
// Assumes ownership.
//
iterator
insert (iterator position, xercesc::DOMElement* x)
{
assert (x->getOwnerDocument () == &doc_);
return iterator (v_.insert (position.base (), ptr (x)));
}
void
insert (iterator position, size_type n, const xercesc::DOMElement& x)
{
difference_type d (v_.end () - position.base ());
v_.insert (position.base (), n, ptr ());
for (base_iterator i (v_.end () - d); n != 0; --n)
{
ptr r (static_cast<xercesc::DOMElement*> (
doc_.importNode (
const_cast<xercesc::DOMElement*> (&x), true)));
*(--i) = r;
}
}
template <typename I>
void
insert (iterator position, const I& begin, const I& end)
{
// This is not the fastest way to do it.
//
if (begin != end)
{
base_iterator p (position.base ());
for (I i (end);;)
{
--i;
ptr r (static_cast<xercesc::DOMElement*> (
doc_.importNode (i->get (), true)));
p = v_.insert (p, r);
if (i == begin)
break;
}
}
}
iterator
erase (iterator position)
{
return iterator (v_.erase (position.base ()));
}
iterator
erase (iterator begin, iterator end)
{
return iterator (v_.erase (begin.base (), end.base ()));
}
public:
// Note that the DOMDocument object of the two sequences being
// swapped should be the same.
//
void
swap (element_sequence& x)
{
assert (&doc_ == &x.doc_);
v_.swap (x.v_);
}
private:
base_sequence v_;
xercesc::DOMDocument& doc_;
};
// Comparison operators.
//
inline bool
operator== (const element_sequence& a, const element_sequence& b)
{
if (a.size () != b.size ())
return false;
element_sequence::const_iterator
ai (a.begin ()), ae (a.end ()), bi (b.begin ());
for (; ai != ae; ++ai, ++bi)
if (!ai->isEqualNode (&(*bi)))
return false;
return true;
}
inline bool
operator!= (const element_sequence& a, const element_sequence& b)
{
return !(a == b);
}
// Attribute set.
//
class attribute_set_common
{
protected:
// Set entry. It can either act as a dangerously destructive
// automatic pointer for DOMAttr or as an entry containing the
// name we are searching for.
//
struct entry
{
~entry ()
{
if (a_)
a_->release ();
}
explicit
entry (xercesc::DOMAttr* a)
: a_ (a), ns_ (0), name_ (0)
{
ns_ = a->getNamespaceURI ();
name_ = ns_ == 0 ? a->getName () : a->getLocalName ();
}
// Note: uses shallow copy.
//
explicit
entry (const XMLCh* ns, const XMLCh* name)
: a_ (0), ns_ (ns), name_ (name)
{
}
entry (const entry& y)
: a_ (y.a_), ns_ (y.ns_), name_ (y.name_)
{
// Yes, hostile takeover.
//
y.a_ = 0;
y.ns_ = 0;
y.name_ = 0;
}
entry&
operator= (const entry& y)
{
if (this != &y)
{
// Yes, hostile takeover.
//
if (a_)
a_->release ();
a_ = y.a_;
ns_ = y.ns_;
name_ = y.name_;
y.a_ = 0;
y.ns_ = 0;
y.name_ = 0;
}
return *this;
}
public:
xercesc::DOMAttr&
operator* () const
{
return *a_;
}
xercesc::DOMAttr*
get () const
{
return a_;
}
const XMLCh*
ns () const
{
return ns_;
}
const XMLCh*
name () const
{
return name_;
}
void
release ()
{
a_ = 0;
}
private:
mutable xercesc::DOMAttr* a_;
mutable const XMLCh* ns_;
mutable const XMLCh* name_;
};
struct entry_cmp
{
bool
operator() (const entry& a, const entry& b) const
{
using xercesc::XMLString;
const XMLCh* ans (a.ns ());
const XMLCh* bns (b.ns ());
const XMLCh* an (a.name ());
const XMLCh* bn (b.name ());
if (ans == 0)
return bns != 0
? true
: (XMLString::compareString (an, bn) < 0);
if (ans != 0 && bns == 0)
return false;
int r (XMLString::compareString (ans, bns));
return r < 0
? true
: (r > 0 ? false : XMLString::compareString (an, bn) < 0);
}
};
typedef std::set<entry, entry_cmp> base_set;
typedef base_set::iterator base_iterator;
typedef base_set::const_iterator base_const_iterator;
};
template <typename C>
class attribute_set: public attribute_set_common
{
public:
typedef xercesc::DOMAttr key_type;
typedef xercesc::DOMAttr value_type;
typedef xercesc::DOMAttr* pointer;
typedef const xercesc::DOMAttr* const_pointer;
typedef xercesc::DOMAttr& reference;
typedef const xercesc::DOMAttr& const_reference;
typedef
iterator_adapter<base_set::iterator, xercesc::DOMAttr>
iterator;
typedef
iterator_adapter<base_set::const_iterator, const xercesc::DOMAttr>
const_iterator;
typedef
iterator_adapter<base_set::reverse_iterator, xercesc::DOMAttr>
reverse_iterator;
typedef
iterator_adapter<base_set::const_reverse_iterator,
const xercesc::DOMAttr>
const_reverse_iterator;
typedef base_set::size_type size_type;
typedef base_set::difference_type difference_type;
typedef base_set::allocator_type allocator_type;
public:
attribute_set (xercesc::DOMDocument& doc)
: doc_ (doc)
{
}
template <typename I>
attribute_set (const I& begin,
const I& end,
xercesc::DOMDocument& doc)
: doc_ (doc)
{
insert (begin, end);
}
attribute_set (const attribute_set& s, xercesc::DOMDocument& doc)
: doc_ (doc)
{
// Can be done faster with the "hinted" insert.
//
insert (s.begin (), s.end ());
}
attribute_set&
operator= (const attribute_set& s)
{
if (this == &s)
return *this;
// Can be done faster with the "hinted" insert.
//
clear ();
insert (s.begin (), s.end ());
return *this;
}
public:
const_iterator
begin () const
{
return const_iterator (s_.begin ());
}
const_iterator
end () const
{
return const_iterator (s_.end ());
}
iterator
begin ()
{
return iterator (s_.begin ());
}
iterator
end ()
{
return iterator (s_.end ());
}
// reverse
//
const_reverse_iterator
rbegin () const
{
return const_reverse_iterator (s_.rbegin ());
}
const_reverse_iterator
rend () const
{
return const_reverse_iterator (s_.rend ());
}
reverse_iterator
rbegin ()
{
return reverse_iterator (s_.rbegin ());
}
reverse_iterator
rend ()
{
return reverse_iterator (s_.rend ());
}
public:
size_type
size () const
{
return s_.size ();
}
size_type
max_size () const
{
return s_.max_size ();
}
bool
empty () const
{
return s_.empty ();
}
void
clear ()
{
s_.clear ();
}
public:
// Makes a deep copy.
//
std::pair<iterator, bool>
insert (const xercesc::DOMAttr& a)
{
entry e (static_cast<xercesc::DOMAttr*> (
doc_.importNode (
const_cast<xercesc::DOMAttr*> (&a), true)));
std::pair<base_iterator, bool> r (s_.insert (e));
return std::pair<iterator, bool> (iterator (r.first), r.second);
}
// Assumes ownership.
//
std::pair<iterator, bool>
insert (xercesc::DOMAttr* a)
{
assert (a->getOwnerDocument () == &doc_);
entry e (a);
std::pair<base_iterator, bool> r (s_.insert (e));
if (!r.second)
e.release (); // Detach the attribute of insert failed.
return std::pair<iterator, bool> (iterator (r.first), r.second);
}
// Makes a deep copy.
//
iterator
insert (iterator position, const xercesc::DOMAttr& a)
{
entry e (static_cast<xercesc::DOMAttr*> (
doc_.importNode (
const_cast<xercesc::DOMAttr*> (&a), true)));
return iterator (s_.insert (position.base (), e));
}
// Assumes ownership.
//
iterator
insert (iterator position, xercesc::DOMAttr* a)
{
assert (a->getOwnerDocument () == &doc_);
entry e (a);
base_iterator r (s_.insert (position.base (), e));
if (r->get () != a)
e.release (); // Detach the attribute of insert failed.
return iterator (r);
}
template <typename I>
void
insert (const I& begin, const I& end)
{
for (I i (begin); i != end; ++i)
{
entry e (static_cast<xercesc::DOMAttr*> (
doc_.importNode (
const_cast<xercesc::DOMAttr*> (&(*i)), true)));
s_.insert (e);
}
}
public:
void
erase (iterator position)
{
s_.erase (position.base ());
}
size_type
erase (const std::basic_string<C>& name)
{
return s_.erase (entry (0, xml::string (name).c_str ()));
}
size_type
erase (const std::basic_string<C>& namespace_,
const std::basic_string<C>& name)
{
return s_.erase (entry (xml::string (namespace_).c_str (),
xml::string (name).c_str ()));
}
size_type
erase (const XMLCh* name)
{
return s_.erase (entry (0, name));
}
size_type
erase (const XMLCh* namespace_, const XMLCh* name)
{
return s_.erase (entry (namespace_, name));
}
void
erase (iterator begin, iterator end)
{
s_.erase (begin.base (), end.base ());
}
public:
size_type
count (const std::basic_string<C>& name) const
{
return s_.count (entry (0, xml::string (name).c_str ()));
}
size_type
count (const std::basic_string<C>& namespace_,
const std::basic_string<C>& name) const
{
return s_.count (entry (xml::string (namespace_).c_str (),
xml::string (name).c_str ()));
}
size_type
count (const XMLCh* name) const
{
return s_.count (entry (0, name));
}
size_type
count (const XMLCh* namespace_, const XMLCh* name) const
{
return s_.count (entry (namespace_, name));
}
// find
//
iterator
find (const std::basic_string<C>& name)
{
return iterator (s_.find (entry (0, xml::string (name).c_str ())));
}
iterator
find (const std::basic_string<C>& namespace_,
const std::basic_string<C>& name)
{
return iterator (
s_.find (entry (xml::string (namespace_).c_str (),
xml::string (name).c_str ())));
}
iterator
find (const XMLCh* name)
{
return iterator (s_.find (entry (0, name)));
}
iterator
find (const XMLCh* namespace_, const XMLCh* name)
{
return iterator (s_.find (entry (namespace_, name)));
}
const_iterator
find (const std::basic_string<C>& name) const
{
return const_iterator (
s_.find (entry (0, xml::string (name).c_str ())));
}
const_iterator
find (const std::basic_string<C>& namespace_,
const std::basic_string<C>& name) const
{
return const_iterator (
s_.find (entry (xml::string (namespace_).c_str (),
xml::string (name).c_str ())));
}
const_iterator
find (const XMLCh* name) const
{
return const_iterator (s_.find (entry (0, name)));
}
const_iterator
find (const XMLCh* namespace_, const XMLCh* name) const
{
return const_iterator (s_.find (entry (namespace_, name)));
}
public:
// Note that the DOMDocument object of the two sets being
// swapped should be the same.
//
void
swap (attribute_set& x)
{
assert (&doc_ == &x.doc_);
s_.swap (x.s_);
}
private:
base_set s_;
xercesc::DOMDocument& doc_;
};
// Comparison operators.
//
template <typename C>
inline bool
operator== (const attribute_set<C>& a, const attribute_set<C>& b)
{
if (a.size () != b.size ())
return false;
typename attribute_set<C>::const_iterator
ai (a.begin ()), ae (a.end ()), bi (b.begin ());
for (; ai != ae; ++ai, ++bi)
if (!ai->isEqualNode (&(*bi)))
return false;
return true;
}
template <typename C>
inline bool
operator!= (const attribute_set<C>& a, const attribute_set<C>& b)
{
return !(a == b);
}
}
}
}
#endif // XSD_CXX_TREE_CONTAINERS_WILDCARD_HXX