This commit is contained in:
Marc Wäckerlin
2009-04-30 15:10:09 +00:00
parent 0871fd927f
commit 13c7266c9f
4 changed files with 264 additions and 39 deletions

152
src/xml-cxx/any.hxx Normal file
View File

@@ -0,0 +1,152 @@
/*! @file
@id $Id$
taken from boost.org boost::Any
*/
// 1 2 3 4 5 6 7 8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
// See http://www.boost.org/libs/any for Documentation.
#ifndef XML_CXX_ANY_INCLUDED
#define XML_CXX_ANY_INCLUDED
#include <algorithm>
#include <typeinfo>
#include <stdexcept>
namespace xml {
class Any {
public: // structors
Any(): content(0) {}
template<typename ValueType> Any(const ValueType& value):
content(new holder<ValueType>(value)) {
}
Any(const Any& other): content(other.content?other.content->clone():0) {}
~Any() {
delete content;
}
public: // modifiers
Any& swap(Any& rhs) {
std::swap(content, rhs.content);
return *this;
}
template<typename ValueType> Any& operator=(const ValueType& rhs) {
Any(rhs).swap(*this);
return *this;
}
Any& operator=(const Any& rhs) {
Any(rhs).swap(*this);
return *this;
}
public: // queries
bool empty() const {
return !content;
}
const std::type_info& type() const {
return content?content->type():typeid(void);
}
private: // types
class placeholder {
public: // structors
virtual ~placeholder() {}
virtual const std::type_info& type() const = 0;
virtual placeholder* clone() const = 0;
};
template<typename ValueType> class holder: public placeholder {
public:
holder(const ValueType& value): held(value) {}
virtual const std::type_info& type() const {
return typeid(ValueType);
}
virtual placeholder* clone() const {
return new holder(held);
}
ValueType held;
};
private: // representation
template<typename ValueType> friend ValueType* any_cast(Any*);
template<typename ValueType> friend ValueType& any_cast(Any&);
placeholder* content;
};
template<typename ValueType> ValueType* any_cast(Any* operand) {
return operand && operand->type() == typeid(ValueType)
? &static_cast<Any::holder<ValueType>*>(operand->content)->held
: 0;
}
template<typename ValueType> const ValueType* any_cast(const Any* operand) {
return any_cast<ValueType>(const_cast<Any*>(operand));
}
template<typename ValueType> ValueType& any_cast(Any& operand) {
if (operand.type()==typeid(ValueType))
return static_cast<Any::holder<ValueType>*>(operand.content)->held;
throw std::bad_cast();
}
template<typename ValueType> const ValueType& any_cast(const Any& operand) {
return any_cast<ValueType>(const_cast<Any&>(operand));
}
}
// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
//
// Distributed under the Boost Software License, Version 1.0. (See
// http://www.boost.org/LICENSE_1_0.txt)
// Boost Software License - Version 1.0 - August 17th, 2003
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endif

View File

@@ -18,7 +18,7 @@
#include <memory>
#include <typeinfo>
#include <stdexcept>
#include <boost/any.hpp>
#include <xml-cxx/any.hxx>
#include <cassert>
#include <iostream>
@@ -829,8 +829,8 @@ namespace xml {
class Serialize {
public:
typedef bool(*FromNodeFunc)(boost::any, const xml::Node&);
typedef bool(*ToNodeFunc)(const boost::any, xml::Node&);
typedef bool(*FromNodeFunc)(Any, const xml::Node&);
typedef bool(*ToNodeFunc)(const Any, xml::Node&);
//! You must call Serialize::className() if you use this constructor!
Serialize() throw();
Serialize(const std::string& className) throw();
@@ -896,8 +896,8 @@ namespace xml {
_xmlFactory = schema;
return *this;
}
virtual void fromNode(boost::any member, const xml::Node& node);
virtual void toNode(const boost::any member, xml::Node& node) const;
virtual void fromNode(Any member, const xml::Node& node);
virtual void toNode(const Any member, xml::Node& node) const;
/*
template<typename TYPE, class ALLOC>
void fromNode(std::list<TYPE, ALLOC>* member, xml::Node& node) {
@@ -905,12 +905,61 @@ namespace xml {
for (xml::Node::size_type i(0); i<node.children(); ++i)
...
}*/
std::map<std::string, boost::any> _xmlNames;
std::map<std::string, Any> _xmlNames;
xml::Factory _xmlFactory;
static std::set<FromNodeFunc> _fromNode;
static std::set<ToNodeFunc> _toNode;
};
const int MAX_NUM(14);
template<int NUM> struct ToType {typedef Serialize Type;};
template<> struct ToType<1> {typedef Serialize Type;};
template<> struct ToType<2> {typedef std::string Type;};
template<> struct ToType<3> {typedef bool Type;};
template<> struct ToType<4> {typedef unsigned char Type;};
template<> struct ToType<5> {typedef signed char Type;};
template<> struct ToType<6> {typedef char Type;};
template<> struct ToType<7> {typedef unsigned short Type;};
template<> struct ToType<8> {typedef signed short Type;};
template<> struct ToType<9> {typedef unsigned int Type;};
template<> struct ToType<10> {typedef signed int Type;};
template<> struct ToType<11> {typedef unsigned long Type;};
template<> struct ToType<12> {typedef signed long Type;};
template<> struct ToType<13> {typedef float Type;};
template<> struct ToType<14> {typedef double Type;};
template<typename T> struct ToNum {static const int NUM = 1;};
template<> struct ToNum<Serialize > {static const int NUM = 1;};
template<> struct ToNum<std::string > {static const int NUM = 2;};
template<> struct ToNum<bool > {static const int NUM = 3;};
template<> struct ToNum<unsigned char > {static const int NUM = 4;};
template<> struct ToNum<signed char > {static const int NUM = 5;};
template<> struct ToNum< char > {static const int NUM = 6;};
template<> struct ToNum<unsigned short> {static const int NUM = 7;};
template<> struct ToNum<signed short> {static const int NUM = 8;};
template<> struct ToNum<unsigned int > {static const int NUM = 9;};
template<> struct ToNum<signed int > {static const int NUM = 10;};
template<> struct ToNum<unsigned long > {static const int NUM = 11;};
template<> struct ToNum<signed long > {static const int NUM = 12;};
template<> struct ToNum<float > {static const int NUM = 13;};
template<> struct ToNum<double > {static const int NUM = 14;};
template<typename T> bool isSerialize() {
return ToNum<T>::NUM == 1;
}
template <typename T, bool GOOD=(ToNum<T>::NUM==1)> struct Mapper {
static Serialize* toSerialize(T& obj) {
return 0;
}
};
template <typename T> struct Mapper<T, true> {
static Serialize* toSerialize(T& obj) {
return dynamic_cast<Serialize*>(&obj);
}
};
template<class TYPE, class ALLOC=std::allocator<TYPE> > class List:
public std::list<TYPE, ALLOC>, public Serialize {
public:
@@ -923,17 +972,20 @@ namespace xml {
std::string itemName("item");
TYPE tmp;
LOG("initXmlMembers List for: "<<typeid(TYPE).name());
if (typeid(TYPE*)==typeid(Serialize*)) {
if (isSerialize<TYPE>()) {
LOG("Liste von Serialize");
Serialize* ser((Serialize*)&tmp);
Serialize* ser(Mapper<TYPE>::toSerialize(tmp));
assert(ser);
assert(ser!=this);
assert((void*)ser==(void*)&tmp);
checkInit(ser);
itemName = **ser->_xmlFactory;
itemName = ser->_xmlFactory->name();
}
_xmlFactory = xml::Node("dummyroot"); // dummy root, (uninitialized exc)
persist(tmp, itemName); // add _reference as child of dummyroot
(*_xmlFactory)[0].limits(0, 0); // any number of children possible
}
virtual void fromNode(boost::any member, const xml::Node& node) {
virtual void fromNode(Any member, const xml::Node& node) {
this->clear();
for (xml::Node::size_type i(0); i<node.parent().children(); ++i) {
TYPE tmp;
@@ -941,7 +993,7 @@ namespace xml {
push_back(tmp);
}
}
virtual void toNode(const boost::any member, xml::Node& node) const {
virtual void toNode(const Any member, xml::Node& node) const {
std::auto_ptr<xml::Node> tpl(node.clone());
xml::Node& parent(node.parent());
parent.clear(); // "node" is now invalid