diff --git a/wrap/ReturnType.cpp b/wrap/ReturnType.cpp index a317a5420..25147e59a 100644 --- a/wrap/ReturnType.cpp +++ b/wrap/ReturnType.cpp @@ -26,7 +26,7 @@ void ReturnType::wrap_result(const string& out, const string& result, if (category == CLASS) { string objCopy, ptrType; ptrType = "Shared" + name; - const bool isVirtual = typeAttributes.at(cppType).isVirtual; + const bool isVirtual = typeAttributes.attributes(cppType).isVirtual; if (isVirtual) { if (isPtr) objCopy = result; diff --git a/wrap/TypeAttributesTable.cpp b/wrap/TypeAttributesTable.cpp index 16055fca1..14c1ab7a4 100644 --- a/wrap/TypeAttributesTable.cpp +++ b/wrap/TypeAttributesTable.cpp @@ -21,42 +21,61 @@ #include "utilities.h" #include +#include +#include +#include // std::ostream_iterator using namespace std; namespace wrap { - /* ************************************************************************* */ - void TypeAttributesTable::addClasses(const vector& classes) { - BOOST_FOREACH(const Class& cls, classes) { - if(!insert(make_pair(cls.qualifiedName("::"), TypeAttributes(cls.isVirtual))).second) - throw DuplicateDefinition("class " + cls.qualifiedName("::")); - } +/* ************************************************************************* */ +const TypeAttributes& TypeAttributesTable::attributes(const string& key) const { + try { + return table_.at(key); + } catch (const out_of_range& oor) { + cerr << "Class::method: key not found: " << oor.what() + << ", methods are:\n"; + using boost::adaptors::map_keys; + ostream_iterator out_it(cerr, "\n"); + boost::copy(table_ | map_keys, out_it); + throw runtime_error("Internal error in wrap"); } +} - /* ************************************************************************* */ - void TypeAttributesTable::addForwardDeclarations(const vector& forwardDecls) { - BOOST_FOREACH(const ForwardDeclaration& fwDec, forwardDecls) { - if(!insert(make_pair(fwDec.name, TypeAttributes(fwDec.isVirtual))).second) - throw DuplicateDefinition("class " + fwDec.name); - } +/* ************************************************************************* */ +void TypeAttributesTable::addClasses(const vector& classes) { + BOOST_FOREACH(const Class& cls, classes) { + if (!table_.insert( + make_pair(cls.qualifiedName("::"), TypeAttributes(cls.isVirtual))).second) + throw DuplicateDefinition("class " + cls.qualifiedName("::")); } +} - /* ************************************************************************* */ - void TypeAttributesTable::checkValidity(const vector& classes) const { - BOOST_FOREACH(const Class& cls, classes) { - // Check that class is virtual if it has a parent - if (!cls.qualifiedParent.empty() && !cls.isVirtual) - throw AttributeError(cls.qualifiedName("::"), - "Has a base class so needs to be declared virtual, change to 'virtual class " - + cls.name + " ...'"); - // Check that parent is virtual as well - Qualified parent = cls.qualifiedParent; - if (!parent.empty() && !at(parent.qualifiedName("::")).isVirtual) - throw AttributeError(parent.qualifiedName("::"), - "Is the base class of " + cls.qualifiedName("::") - + ", so needs to be declared virtual"); - } +/* ************************************************************************* */ +void TypeAttributesTable::addForwardDeclarations( + const vector& forwardDecls) { + BOOST_FOREACH(const ForwardDeclaration& fwDec, forwardDecls) { + if (!table_.insert(make_pair(fwDec.name, TypeAttributes(fwDec.isVirtual))).second) + throw DuplicateDefinition("class " + fwDec.name); } +} + +/* ************************************************************************* */ +void TypeAttributesTable::checkValidity(const vector& classes) const { + BOOST_FOREACH(const Class& cls, classes) { + // Check that class is virtual if it has a parent + if (!cls.qualifiedParent.empty() && !cls.isVirtual) + throw AttributeError(cls.qualifiedName("::"), + "Has a base class so needs to be declared virtual, change to 'virtual class " + + cls.name + " ...'"); + // Check that parent is virtual as well + Qualified parent = cls.qualifiedParent; + if (!parent.empty() && !table_.at(parent.qualifiedName("::")).isVirtual) + throw AttributeError(parent.qualifiedName("::"), + "Is the base class of " + cls.qualifiedName("::") + + ", so needs to be declared virtual"); + } +} } diff --git a/wrap/TypeAttributesTable.h b/wrap/TypeAttributesTable.h index d2a346bfc..9b1c2acbc 100644 --- a/wrap/TypeAttributesTable.h +++ b/wrap/TypeAttributesTable.h @@ -27,9 +27,9 @@ namespace wrap { - // Forward declarations - class Class; - +// Forward declarations +class Class; + /** Attributes about valid classes, both for classes defined in this module and * also those forward-declared from others. At the moment this only contains * whether the class is virtual, which is used to know how to copy the class, @@ -37,18 +37,33 @@ namespace wrap { */ struct TypeAttributes { bool isVirtual; - TypeAttributes() : isVirtual(false) {} - TypeAttributes(bool isVirtual) : isVirtual(isVirtual) {} + TypeAttributes() : + isVirtual(false) { + } + TypeAttributes(bool isVirtual) : + isVirtual(isVirtual) { + } }; /** Map of type names to attributes. */ -class TypeAttributesTable : public std::map { +class TypeAttributesTable { + + std::map table_; + public: - TypeAttributesTable() {} + + /// Constructor + TypeAttributesTable() { + } void addClasses(const std::vector& classes); - void addForwardDeclarations(const std::vector& forwardDecls); + void addForwardDeclarations( + const std::vector& forwardDecls); + /// Access attributes associated with key, informative failure + const TypeAttributes& attributes(const std::string& key) const; + + /// Check that all virtual classes are properly defined void checkValidity(const std::vector& classes) const; };