def finalize(cls, finalize_pure_virtuals=False): """ Attempt to finalize a class by not exposing virtual methods. Still exposes in the case of pure virtuals otherwise the class could not be instantiated. """ if isinstance(cls, pd.mdecl_wrapper_t): for x in cls: finalize(x) else: matcher = pd.virtuality_type_matcher(pd.VIRTUALITY_TYPES.VIRTUAL) if finalize_pure_virtuals: matcher = matcher | pd.virtuality_type_matcher( pd.VIRTUALITY_TYPES.PURE_VIRTUAL) members = cls.decls(matcher, decl_type=pd.member_calldef_t, allow_empty=True) members.set_virtuality(pd.VIRTUALITY_TYPES.NOT_VIRTUAL) cls.decls(pd.access_type_matcher_t(pd.ACCESS_TYPES.PROTECTED), allow_empty=True).exclude() cls.decls(pd.access_type_matcher_t(pd.ACCESS_TYPES.PRIVATE), allow_empty=True).exclude() wrapper_needs = cls.is_wrapper_needed() if len(wrapper_needs): print "Finalize failed for: ", cls.name for x in wrapper_needs: print " ", x
def finalize(cls, finalize_pure_virtuals=False): """ Attempt to finalize a class by not exposing virtual methods. Still exposes in the case of pure virtuals otherwise the class could not be instantiated. """ if isinstance(cls, pd.mdecl_wrapper_t): for x in cls: finalize(x) else: matcher = pd.virtuality_type_matcher( pd.VIRTUALITY_TYPES.VIRTUAL ) if finalize_pure_virtuals: matcher = matcher | pd.virtuality_type_matcher( pd.VIRTUALITY_TYPES.PURE_VIRTUAL) members = cls.decls( matcher, decl_type=pd.member_calldef_t, allow_empty=True) members.set_virtuality( pd.VIRTUALITY_TYPES.NOT_VIRTUAL ) cls.decls(pd.access_type_matcher_t(pd.ACCESS_TYPES.PROTECTED),allow_empty=True).exclude() cls.decls(pd.access_type_matcher_t(pd.ACCESS_TYPES.PRIVATE),allow_empty=True).exclude() wrapper_needs = cls.is_wrapper_needed() if len(wrapper_needs): print "Finalize failed for: ", cls.name for x in wrapper_needs: print " ", x
def exportInterfaceClasses( mb ): """export virtual classes. These classes can not instantiated directly from python. """ # do not add AlignlibBase. Adding it causes # problems with get/set/cloneToolkit. The warning is # # WARNING: alignlib::Fragmentor [class] # > warning W1023: Py++ will generate class wrapper - there are few functions that should be redefined in class wrapper. The functions are: getToolkit. # Later, compilation will fail with: # /usr/include/boost/python/object/value_holder.hpp: At global scope: # /usr/include/boost/python/object/value_holder.hpp: In instantiation of boost::python::objects::value_holder<Fragmentor_wrapper>: # /usr/include/boost/type_traits/alignment_of.hpp:52: instantiated from 'const size_t boost::detail::alignment_of_impl<boost::python::objects::value_holder<Fragmentor_wrapper> >::value' # /usr/include/boost/type_traits/alignment_of.hpp:61: instantiated from 'boost::alignment_of<boost::python::objects::value_holder<Fragmentor_wrapper> >' # /usr/include/boost/python/object/instance.hpp:30: instantiated from 'boost::python::objects::instance<boost::python::objects::value_holder<Fragmentor_wrapper> >' # /usr/include/boost/python/object/instance.hpp:44: instantiated from 'const size_t boost::python::objects::additional_instance_size<boost::python::objects::value_holder<Fragmentor_wrapper> >::value' # /usr/include/boost/python/class.hpp:499: instantiated from 'void boost::python::class_<T, X1, X2, X3>::initialize(const DefVisitor&) [with DefVisitor = boost::python::init<mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_>, W = Fragmentor_wrapper, X1 = boost::python::bases<alignlib::AlignlibBase, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_>, X2 = boost::noncopyable_::noncopyable, X3 = boost::python::detail::not_specified]' # /usr/include/boost/python/class.hpp:629: instantiated from 'boost::python::class_<T, X1, X2, X3>::class_(const char*, const char*) [with W = Fragmentor_wrapper, X1 = boost::python::bases<alignlib::AlignlibBase, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_>, X2 = boost::noncopyable_::noncopyable, X3 = boost::python::detail::not_specified]' # modules/Fragmentor.pypp.cpp:43: instantiated from here # /usr/include/boost/python/object/value_holder.hpp:66: error: cannot declare field 'boost::python::objects::value_holder<Fragmentor_wrapper>::m_held' to be of abstract type 'Fragmentor_wrapper' # modules/Fragmentor.pypp.cpp:11: note: because the following virtual functions are pure within 'Fragmentor_wrapper': # ../alignlib/Fragmentor.h:63: note: virtual alignlib::HFragmentor alignlib::Fragmentor::getClone() const # ../alignlib/Fragmentor.h:63: note: virtual alignlib::HFragmentor alignlib::Fragmentor::getNew() const # ../alignlib/Fragmentor.h:72: note: virtual alignlib::HFragmentVector alignlib::Fragmentor::fragment(alignlib::HAlignment&, const alignlib::HAlignandum&, const alignlib::HAlignandum&) # error: command 'gcc' failed with exit status 1 classes_to_export = set( [ 'AlignlibBase', 'Toolkit', 'Alignandum', 'Sequence', 'Profile', 'MultipleAlignment', 'MultAlignment', 'Alignator', 'MultipleAlignator', 'Iterator', 'Encoder', 'Fragmentor', 'Alignment', 'AlignmentIterator', 'Scorer', 'Weightor', 'LogOddor', 'Regularizor', 'Iterator2D', 'ResiduePair', 'Alignatum', 'EVDParameters', 'NormalDistributionParameters', 'Distor', 'Treetor', 'Tree', 'DistanceMatrix', 'Segment', ]) ## TODO export substitution matrix ## include all classes mb.classes( lambda x: x.name in classes_to_export ).include() ## do not include the increment/decrement and dereference operators, because there is no equivalent in python ## exlude functions while testing. Need to map return types later. ## default: exclude most operators mb.member_operators( lambda x: x.name in ("operator++", "operator--", "operator*", "operator->", "operator()", "operator[]") ).exclude() # mb.member_functions( lambda x: x.name == "getToolkit").exclude() # mb.member_functions( lambda x: x.name == "setToolkit").exclude() # mb.member_functions( lambda x: x.name == "cloneToolkit").exclude() ## do not export the internal iterator interfaces. This makes Alignment ## virtual and the wrapper will cause compilation to fail. mb.classes( lambda x: x.name in ("Iterator", "ConstIterator")).exclude() ## see http://article.gmane.org/gmane.comp.python.c++/10177 ## The following code is used to remove the wrapper classes for purely virtual classes. for c in classes_to_export: cls = mb.class_( c ) ## remove virtual member functions. This will result in a class to be ## not virtual and hence no wrapper. members = cls.decls( declarations.virtuality_type_matcher( declarations.VIRTUALITY_TYPES.PURE_VIRTUAL ), decl_type=declarations.calldef.member_calldef_t, allow_empty=True) members.set_virtuality( declarations.VIRTUALITY_TYPES.NOT_VIRTUAL ) members = cls.decls( declarations.virtuality_type_matcher( declarations.VIRTUALITY_TYPES.ALL ), decl_type=declarations.calldef.member_calldef_t, allow_empty=True) members.set_virtuality( declarations.VIRTUALITY_TYPES.NOT_VIRTUAL ) ## do not wrap constructors, because compilation will fail for ## abstract classes. try: cls.constructors().exclude() except RuntimeError: print "no construtors for %s" % c ## export load/save functionality classes_with_load_save = ("Alignandum", "Encoder") exportSave( mb, classes_with_load_save, options, generic = False ) exportLoad( mb, classes_with_load_save, options, generic = False )
wrapperOrderFile = open(os.path.join(task.bldpath, '.wrapper_order.py'), 'a') wrapperOrderFile.write(libraryName + '\n') wrapperOrderFile.close() # Set a standard name for every declaration try: for decl in mb.classes(): from pyplusplus.decl_wrappers.algorithm import create_valid_name decl.alias = create_valid_name(decl.name) except: pass # Disable virtuality unless specifically asked to do otherwise: this should avoid overrides # and increase simulation speed if( not task.virtuality ): members = mb.global_ns.calldefs( declarations.virtuality_type_matcher( declarations.VIRTUALITY_TYPES.VIRTUAL ) , allow_empty=True) if( members ): members.set_virtuality( declarations.VIRTUALITY_TYPES.NOT_VIRTUAL ) # Execute includes user-specified code for customCodeBlock in task.custom_code_include: try: exec customCodeBlock in locals() except: if Logs.verbose: import traceback traceback.print_exc() print '\nWhile Processing FILEs: \n' + str(sources) + '\nLines: ' + str(customCodeBlock) + '\n' # Execute user-specified code