Adding Boost::Python wrapping
This commit is contained in:
parent
80dd17bbef
commit
d8e82643e6
|
@ -13,22 +13,22 @@ SET ( cpps Circuit.cpp
|
|||
Subckt.cpp
|
||||
Value.cpp
|
||||
)
|
||||
#SET ( pycpps PySpice.cpp
|
||||
# )
|
||||
SET ( pycpps PySpice.cpp
|
||||
)
|
||||
|
||||
ADD_LIBRARY(spice ${cpps})
|
||||
TARGET_LINK_LIBRARIES(spice)
|
||||
SET_TARGET_PROPERTIES(spice PROPERTIES VERSION 1.0 SOVERSION 1)
|
||||
INSTALL(TARGETS spice DESTINATION lib${LIB_SUFFIX} )
|
||||
|
||||
#IF(Boost_FOUND)
|
||||
# ADD_LIBRARY(pySPICE MODULE ${pycpps})
|
||||
# SET_TARGET_PROPERTIES(pySPICE PROPERTIES
|
||||
# OUTPUT_NAME "SPICE"
|
||||
# PREFIX ""
|
||||
# )
|
||||
# TARGET_LINK_LIBRARIES(pySPICE spice ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
|
||||
# INSTALL(TARGETS pySPICE DESTINATION ${PYTHON_SITE_PACKAGES})
|
||||
#ENDIF(Boost_FOUND)
|
||||
IF(Boost_FOUND)
|
||||
ADD_LIBRARY(pySPICE MODULE ${pycpps})
|
||||
SET_TARGET_PROPERTIES(pySPICE PROPERTIES
|
||||
OUTPUT_NAME "SPICE"
|
||||
PREFIX ""
|
||||
)
|
||||
TARGET_LINK_LIBRARIES(pySPICE spice ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
|
||||
INSTALL(TARGETS pySPICE DESTINATION ${PYTHON_SITE_PACKAGES})
|
||||
ENDIF(Boost_FOUND)
|
||||
|
||||
INSTALL(FILES ${hpps} DESTINATION include/vlsisapd/spice)
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
using namespace std;
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
|
||||
using namespace boost::python;
|
||||
|
||||
#include "vlsisapd/spice/Instances.h"
|
||||
#include "vlsisapd/spice/Sources.h"
|
||||
#include "vlsisapd/spice/Subckt.h"
|
||||
#include "vlsisapd/spice/Circuit.h"
|
||||
#include "vlsisapd/spice/SpiceException.h"
|
||||
|
||||
#include "vlsisapd/spice/PySTLMapWrapper.h"
|
||||
|
||||
namespace SPICE {
|
||||
void translator(SpiceException const& e) {
|
||||
PyErr_SetString(PyExc_UserWarning, e.what());
|
||||
}
|
||||
|
||||
// for optional arguments
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(addLibrary_overloads, addLibrary, 1, 2);
|
||||
|
||||
BOOST_PYTHON_MODULE(SPICE) {
|
||||
|
||||
// vector and map wrapping for Spice::Instance
|
||||
class_<std::vector<std::string> >("ConnectorsVector")
|
||||
.def(vector_indexing_suite<std::vector<std::string> >())
|
||||
;
|
||||
STL_MAP_WRAPPING(std::string, std::string, "ParametersMap")
|
||||
// class SPICE::Instance
|
||||
class_<Instance, Instance*>("Instance", init<std::string, std::string>())
|
||||
// accessors
|
||||
.def("getName" , &Instance::getName )
|
||||
.def("getModel" , &Instance::getModel )
|
||||
.def("getParameterValue", &Instance::getParameterValue )
|
||||
// modifiers
|
||||
.def("addConnector", &Instance::addConnector )
|
||||
.def("addParameter", &Instance::addParameter )
|
||||
// stl containers
|
||||
.def("getConnectors", &Instance::getConnectors, return_value_policy<copy_const_reference>())
|
||||
.def("getParameters", &Instance::getParameters, return_value_policy<copy_const_reference>())
|
||||
;
|
||||
|
||||
// class SPICE::Mosfet
|
||||
class_<Mosfet, bases<Instance> >("Mosfet", init<std::string, std::string, std::string, std::string, std::string, std::string>())
|
||||
// accessors
|
||||
.def("getDrain" , &Mosfet::getDrain )
|
||||
.def("getGrid" , &Mosfet::getGrid )
|
||||
.def("getSource", &Mosfet::getSource )
|
||||
.def("getBulk" , &Mosfet::getBulk )
|
||||
;
|
||||
|
||||
// class SPICE::Capacitor
|
||||
class_<Capacitor, bases<Instance> >("Capacitor", init<std::string, std::string, std::string, std::string>())
|
||||
// accessors
|
||||
.def("getPositive", &Capacitor::getPositive )
|
||||
.def("getNegative", &Capacitor::getNegative )
|
||||
.def("getValue" , &Capacitor::getValue )
|
||||
;
|
||||
|
||||
// class SPICE::Resistor
|
||||
class_<Resistor, bases<Instance> >("Resistor", init<std::string, std::string, std::string, std::string>())
|
||||
// accessors
|
||||
.def("getFirst" , &Resistor::getFirst )
|
||||
.def("getSecond", &Resistor::getSecond )
|
||||
.def("getValue" , &Resistor::getValue )
|
||||
;
|
||||
|
||||
// class SPICE::Source !! abstract class !!
|
||||
class_<Source, Source*, boost::noncopyable>("Source", no_init)
|
||||
// accessors
|
||||
.def("getName" , &Source::getName )
|
||||
.def("getPositive", &Source::getPositive )
|
||||
.def("getNegative", &Source::getNegative )
|
||||
.def("getValue" , &Source::getValue )
|
||||
;
|
||||
|
||||
// class SPICE::Voltage
|
||||
class_<Voltage, bases<Source> >("Voltage", init<std::string, std::string, std::string, std::string>())
|
||||
;
|
||||
|
||||
// class SPICE::Current
|
||||
class_<Current, bases<Source> >("Current", init<std::string, std::string, std::string, std::string>())
|
||||
;
|
||||
|
||||
|
||||
// vector indexing for Spice::Subckt
|
||||
// InterfacesVector = ConnectorsVector already exists
|
||||
class_<std::vector<Instance*> >("InstancesVector")
|
||||
.def(vector_indexing_suite<std::vector<Instance*>, true>())
|
||||
;
|
||||
// ParametersMap is already defined
|
||||
// class SPICE::Subckt
|
||||
class_<Subckt, Subckt*>("Subckt", init<std::string>())
|
||||
// accessors
|
||||
.def("getName", &Subckt::getName )
|
||||
// modifiers
|
||||
.def("addInterface", &Subckt::addInterface )
|
||||
.def("addInstance" , &Subckt::addInstance )
|
||||
.def("addParameter", &Subckt::addParameter )
|
||||
// stl containers
|
||||
.def("getInterfaces", &Subckt::getInterfaces, return_value_policy<copy_const_reference>())
|
||||
.def("getInstances" , &Subckt::getInstances , return_value_policy<copy_const_reference>())
|
||||
.def("getParameters", &Subckt::getParameters, return_value_policy<copy_const_reference>())
|
||||
;
|
||||
|
||||
// vector indexing for Spice::Circuit
|
||||
class_<std::vector<std::pair<std::string, std::string> > > ("LibrariesVector")
|
||||
.def(vector_indexing_suite<std::vector<std::pair<std::string, std::string> > >())
|
||||
;
|
||||
// InstancesVector already exists
|
||||
// ParametersMap = OptionsMap already exists
|
||||
class_<std::vector<Source*> >("SourcesVector")
|
||||
.def(vector_indexing_suite<std::vector<Source*> >())
|
||||
;
|
||||
class_<std::vector<Subckt*> >("SubcktsVector")
|
||||
.def(vector_indexing_suite<std::vector<Subckt*> >())
|
||||
;
|
||||
// class SPICE::Circuit
|
||||
class_<Circuit, Circuit*>("Circuit", init<>())
|
||||
// properties
|
||||
.add_property("title", &Circuit::getTitle, &Circuit::setTitle )
|
||||
// modifiers
|
||||
.def("addInclude" , &Circuit::addInclude )
|
||||
.def("addLibrary" , &Circuit::addLibrary , addLibrary_overloads())
|
||||
.def("addInstance" , &Circuit::addInstance )
|
||||
.def("addSource" , &Circuit::addSource )
|
||||
.def("addOption" , &Circuit::addOption )
|
||||
.def("addParameter" , &Circuit::addParameter )
|
||||
.def("addSubckt" , &Circuit::addSubckt , return_value_policy<reference_existing_object>())
|
||||
// stl containers
|
||||
.def("getIncludes" , &Circuit::getIncludes , return_value_policy<copy_const_reference>())
|
||||
.def("getLibraries" , &Circuit::getLibraries , return_value_policy<copy_const_reference>())
|
||||
.def("getOptions" , &Circuit::getOptions , return_value_policy<copy_const_reference>())
|
||||
.def("getParameters", &Circuit::getParameters, return_value_policy<copy_const_reference>())
|
||||
.def("getSubckts" , &Circuit::getSubckts , return_value_policy<copy_const_reference>())
|
||||
.def("getInstances" , &Circuit::getInstances , return_value_policy<copy_const_reference>())
|
||||
.def("getSources" , &Circuit::getSources , return_value_policy<copy_const_reference>())
|
||||
// others
|
||||
.def("readFromFile" , &Circuit::readFromFile , return_value_policy<reference_existing_object>())
|
||||
.staticmethod("readFromFile")
|
||||
.def("writeToFile" , &Circuit::writeToFile )
|
||||
|
||||
;
|
||||
|
||||
// SpiceException translator
|
||||
register_exception_translator<SpiceException>(translator)
|
||||
;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
#include <map>
|
||||
|
||||
#include <boost/python.hpp>
|
||||
|
||||
namespace SPICE {
|
||||
// since we want to wrap std::map<type, Class*> with cimple pointers (no boost::shared_ptr),
|
||||
// we cannot use map_indexing_suite which has not the right return_value_policy.
|
||||
// std::maps with no points value are wrapped using map_indexing_suite technique.
|
||||
//
|
||||
// This templated map_item struct is intended to be used for 'manual' wrapping:
|
||||
template<class Key, class Val>
|
||||
struct map_item {
|
||||
typedef std::map<Key,Val> Map;
|
||||
|
||||
static Val get(Map & self, const Key idx) {
|
||||
if (self.find(idx) == self.end()) {
|
||||
PyErr_SetString(PyExc_KeyError,"Map key not found");
|
||||
throw_error_already_set();
|
||||
}
|
||||
return self[idx];
|
||||
}
|
||||
|
||||
static void set(Map& self, const Key idx, const Val val) { self[idx]=val; }
|
||||
static void del(Map& self, const Key n) { self.erase(n); }
|
||||
static bool in (Map const& self, const Key n) { return self.find(n) != self.end(); }
|
||||
|
||||
static list keys(Map const& self) {
|
||||
list t;
|
||||
for(typename Map::const_iterator it = self.begin() ; it!=self.end() ; ++it)
|
||||
t.append(it->first);
|
||||
return t;
|
||||
}
|
||||
|
||||
static list values(Map const& self) {
|
||||
list t;
|
||||
for(typename Map::const_iterator it=self.begin(); it!=self.end(); ++it)
|
||||
t.append(it->second);
|
||||
return t;
|
||||
}
|
||||
|
||||
static list items(Map const& self) {
|
||||
list t;
|
||||
for(typename Map::const_iterator it=self.begin(); it!=self.end(); ++it)
|
||||
t.append( make_tuple(it->first, it->second) );
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
#define STL_MAP_WRAPPING_PTR(KEY_TYPE, VALUE_TYPE, PYTHON_TYPE_NAME) \
|
||||
class_<std::pair<const KEY_TYPE, VALUE_TYPE> >((std::string(PYTHON_TYPE_NAME)+std::string("DATA")).c_str()) \
|
||||
.def_readonly ("key" , &std::pair<const KEY_TYPE, VALUE_TYPE>::first ) \
|
||||
.def_readwrite("value", &std::pair<const KEY_TYPE, VALUE_TYPE>::second) \
|
||||
; \
|
||||
class_<std::map<KEY_TYPE, VALUE_TYPE> >(PYTHON_TYPE_NAME) \
|
||||
.def("__len__" , &std::map<KEY_TYPE, VALUE_TYPE>::size) \
|
||||
.def("__iter__" , boost::python::iterator<std::map<KEY_TYPE, VALUE_TYPE>, return_internal_reference<> >()) \
|
||||
.def("__getitem__" , &map_item<KEY_TYPE, VALUE_TYPE>().get, return_internal_reference<>()) \
|
||||
.def("__setitem__" , &map_item<KEY_TYPE, VALUE_TYPE>().set ) \
|
||||
.def("__delitem__" , &map_item<KEY_TYPE, VALUE_TYPE>().del ) \
|
||||
.def("__contains__", &map_item<KEY_TYPE, VALUE_TYPE>().in ) \
|
||||
.def("clear" , &std::map<KEY_TYPE, VALUE_TYPE>::clear ) \
|
||||
.def("has_key" , &map_item<KEY_TYPE, VALUE_TYPE>().in ) \
|
||||
.def("keys" , &map_item<KEY_TYPE, VALUE_TYPE>().keys ) \
|
||||
.def("values" , &map_item<KEY_TYPE, VALUE_TYPE>().values) \
|
||||
.def("items" , &map_item<KEY_TYPE, VALUE_TYPE>().items ) \
|
||||
;
|
||||
|
||||
#define STL_MAP_WRAPPING(KEY_TYPE, VALUE_TYPE, PYTHON_TYPE_NAME) \
|
||||
class_<std::pair<const KEY_TYPE, VALUE_TYPE> >((std::string(PYTHON_TYPE_NAME)+std::string("DATA")).c_str()) \
|
||||
.def_readonly ("key" , &std::pair<const KEY_TYPE, VALUE_TYPE>::first ) \
|
||||
.def_readwrite("value", &std::pair<const KEY_TYPE, VALUE_TYPE>::second) \
|
||||
; \
|
||||
class_<std::map<KEY_TYPE, VALUE_TYPE> >(PYTHON_TYPE_NAME) \
|
||||
.def("__len__" , &std::map<KEY_TYPE, VALUE_TYPE>::size) \
|
||||
.def("__iter__" , boost::python::iterator<std::map<KEY_TYPE, VALUE_TYPE>, return_internal_reference<> >()) \
|
||||
.def("__getitem__" , &map_item<KEY_TYPE, VALUE_TYPE>().get ) \
|
||||
.def("__setitem__" , &map_item<KEY_TYPE, VALUE_TYPE>().set ) \
|
||||
.def("__delitem__" , &map_item<KEY_TYPE, VALUE_TYPE>().del ) \
|
||||
.def("__contains__", &map_item<KEY_TYPE, VALUE_TYPE>().in ) \
|
||||
.def("clear" , &std::map<KEY_TYPE, VALUE_TYPE>::clear ) \
|
||||
.def("has_key" , &map_item<KEY_TYPE, VALUE_TYPE>().in ) \
|
||||
.def("keys" , &map_item<KEY_TYPE, VALUE_TYPE>().keys ) \
|
||||
.def("values" , &map_item<KEY_TYPE, VALUE_TYPE>().values) \
|
||||
.def("items" , &map_item<KEY_TYPE, VALUE_TYPE>().items ) \
|
||||
;
|
||||
|
||||
} // namespace
|
|
@ -20,20 +20,20 @@ class Subckt {
|
|||
Subckt(std::string name): _name(name), _interfaces(), _instances(), _parameters() {}
|
||||
~Subckt() {}
|
||||
|
||||
inline std::string getName();
|
||||
inline std::vector<std::string>& getInterfaces();
|
||||
inline std::vector<Instance*>& getInstances();
|
||||
inline std::map<std::string, std::string>& getParameters();
|
||||
inline const std::string getName();
|
||||
inline const std::vector<std::string>& getInterfaces();
|
||||
inline const std::vector<Instance*>& getInstances();
|
||||
inline const std::map<std::string, std::string>& getParameters();
|
||||
|
||||
inline void addInterface(std::string);
|
||||
inline void addInstance (Instance*);
|
||||
|
||||
void addParameter(std::string, std::string);
|
||||
};
|
||||
inline std::string Subckt::getName() { return _name; }
|
||||
inline std::vector<std::string>& Subckt::getInterfaces() { return _interfaces; }
|
||||
inline std::vector<Instance*>& Subckt::getInstances() { return _instances; }
|
||||
inline std::map<std::string, std::string>& Subckt::getParameters() { return _parameters; }
|
||||
inline const std::string Subckt::getName() { return _name; }
|
||||
inline const std::vector<std::string>& Subckt::getInterfaces() { return _interfaces; }
|
||||
inline const std::vector<Instance*>& Subckt::getInstances() { return _instances; }
|
||||
inline const std::map<std::string, std::string>& Subckt::getParameters() { return _parameters; }
|
||||
|
||||
inline void Subckt::addInterface(std::string name) { _interfaces.push_back(name); }
|
||||
inline void Subckt::addInstance(Instance* inst) { _instances.push_back(inst); }
|
||||
|
|
Loading…
Reference in New Issue