Skip to main content
Code Review

Return to Question

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

This was tested with a g++ 4.7 snapshot on Debian squeeze. It uses C++ 11 features, specifically variadic templates, so requires a recent compiler. This is based on the answer to ""unpacking" a tuple to call a matching function pointer" the answer to ""unpacking" a tuple to call a matching function pointer".

This was tested with a g++ 4.7 snapshot on Debian squeeze. It uses C++ 11 features, specifically variadic templates, so requires a recent compiler. This is based on the answer to ""unpacking" a tuple to call a matching function pointer".

This was tested with a g++ 4.7 snapshot on Debian squeeze. It uses C++ 11 features, specifically variadic templates, so requires a recent compiler. This is based on the answer to ""unpacking" a tuple to call a matching function pointer".

Notice removed Draw attention by Community Bot
Bounty Ended with Daan's answer chosen by Community Bot
changed formatting to make it simpler to understand which parts are actually part of the code
Source Link
Edward
  • 67.2k
  • 4
  • 120
  • 284

cpptup_conv_pif.cpp

###################
cpptup_conv_pif.cpp
###################
#include <tuple>
#include <string>
#include <iostream>
using std::cout;
using std::endl;
using std::string;
#include <boost/python/tuple.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/object.hpp>
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/def.hpp>
using boost::python::extract;
template<int ...> struct seq{};
template<int N, int ...S> struct gens : gens<N-1, N-1, S...>{};
template<int ...S> struct gens<0, S...> {typedef seq<S...> type;};
template <typename ...Args>
struct cpptuple2pytuple_wrapper
{
 std::tuple<Args...> params;
 cpptuple2pytuple_wrapper(const std::tuple<Args...>& _params):params(_params){}
 boost::python::tuple delayed_dispatch()
 {
 return callFunc(typename gens<sizeof...(Args)>::type());
 }
 template<int ...S>
 boost::python::tuple callFunc(seq<S...>)
 {
 return boost::python::make_tuple(std::get<S>(params) ...);
 }
};
template <typename ...Args>
struct pytuple2cpptuple_wrapper
{
 boost::python::tuple params;
 pytuple2cpptuple_wrapper(const boost::python::tuple& _params):params(_params){}
 std::tuple<Args...> delayed_dispatch()
 {
 return callFunc(typename gens<sizeof...(Args)>::type());
 }
 template<int ...S>
 std::tuple<Args...> callFunc(seq<S...>)
 {
 return std::make_tuple((static_cast<Args>(extract<Args>(params[S])))...);
 }
};
// Convert (C++) tuple to (Python) tuple as PyObject*.
template<typename ... Args> PyObject* cpptuple2pytuple(const std::tuple<Args...>& t)
{
 cpptuple2pytuple_wrapper<Args...> wrapper(t);
 boost::python::tuple bpt = wrapper.delayed_dispatch();
 return boost::python::incref(boost::python::object(bpt).ptr());
}
// Convert (Python) tuple to (C++) tuple.
template<typename ... Args> std::tuple<Args...> pytuple2cpptuple(PyObject* obj)
{
 boost::python::tuple tup(boost::python::borrowed(obj));
 pytuple2cpptuple_wrapper<Args...> wrapper(tup);
 std::tuple<Args...> bpt = wrapper.delayed_dispatch();
 return bpt;
}
template<typename ... Args>
struct cpptuple_to_python_tuple
{
 static PyObject* convert(const std::tuple<Args...>& t)
 {
 return cpptuple2pytuple<Args...>(t);
 }
};
template<typename ... Args>
struct cpptuple_from_python_tuple
{
 cpptuple_from_python_tuple()
 {
 boost::python::converter::registry::push_back(
 &convertible,
 &construct,
 boost::python::type_id<std::tuple<Args...> >());
 }
 static void* convertible(PyObject* obj_ptr)
 {
 if (!PyTuple_CheckExact(obj_ptr)) return 0;
 return obj_ptr;
 }
 static void construct(
 PyObject* obj_ptr,
 boost::python::converter::rvalue_from_python_stage1_data* data)
 {
 void* storage = (
 (boost::python::converter::rvalue_from_python_storage<std::tuple<Args...> >*)
 data)->storage.bytes;
 new (storage) std::tuple<Args...>(pytuple2cpptuple<Args...>(obj_ptr));
 data->convertible = storage;
 }
};
template<typename ...Args> void create_tuple_converter()
{
 boost::python::to_python_converter<std::tuple<Args...>, cpptuple_to_python_tuple<Args...> >();
 cpptuple_from_python_tuple<Args...>();
}
void export_cpptuple_conv()
{
 create_tuple_converter<int, float>();
 create_tuple_converter<int, double, string>();
}
std::tuple<int, float> tupid1(std::tuple<int, float> t){return t;}
std::tuple<int, double, string> tupid2(std::tuple<int, double, string> t){return t;}
BOOST_PYTHON_MODULE(bptuple)
{
 export_cpptuple_conv();
 boost::python::def("tupid1", tupid1);
 boost::python::def("tupid2", tupid2);
}

SConstruct

###################################################
SConstruct
###################################################
#!/usr/bin/python
import commands, glob, os
def pyversion():
 pystr = commands.getoutput('python -V')
 version = pystr.split(' ')[1]
 major, minor = version.split('.')[:2]
 return major + '.' + minor
boost_python_env = Environment(
 #CXX="g++",
 CXX="g++-4.7",
 CPPPATH=["/usr/include/python"+pyversion()],
 CXXFLAGS="-ftemplate-depth-100 -fno-strict-aliasing -ansi -Wextra -Wall -Werror -Wno-unused-function -g -O3 -std=c++11",
 CPPDEFINES=['BOOST_PYTHON_DYNAMIC_LIB'],
 LIBPATH=["/usr/lib/python"+pyversion()+"/config"],
 LIBS=["python"+pyversion(), "m", "boost_python"],
 SHLIBPREFIX="", #gets rid of lib prefix
 )
boost_python_env.SharedLibrary(target="bptuple", source=["cpptup_conv_pif.cpp"])
###################################################
###################
cpptup_conv_pif.cpp
###################
#include <tuple>
#include <string>
#include <iostream>
using std::cout;
using std::endl;
using std::string;
#include <boost/python/tuple.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/object.hpp>
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/def.hpp>
using boost::python::extract;
template<int ...> struct seq{};
template<int N, int ...S> struct gens : gens<N-1, N-1, S...>{};
template<int ...S> struct gens<0, S...> {typedef seq<S...> type;};
template <typename ...Args>
struct cpptuple2pytuple_wrapper
{
 std::tuple<Args...> params;
 cpptuple2pytuple_wrapper(const std::tuple<Args...>& _params):params(_params){}
 boost::python::tuple delayed_dispatch()
 {
 return callFunc(typename gens<sizeof...(Args)>::type());
 }
 template<int ...S>
 boost::python::tuple callFunc(seq<S...>)
 {
 return boost::python::make_tuple(std::get<S>(params) ...);
 }
};
template <typename ...Args>
struct pytuple2cpptuple_wrapper
{
 boost::python::tuple params;
 pytuple2cpptuple_wrapper(const boost::python::tuple& _params):params(_params){}
 std::tuple<Args...> delayed_dispatch()
 {
 return callFunc(typename gens<sizeof...(Args)>::type());
 }
 template<int ...S>
 std::tuple<Args...> callFunc(seq<S...>)
 {
 return std::make_tuple((static_cast<Args>(extract<Args>(params[S])))...);
 }
};
// Convert (C++) tuple to (Python) tuple as PyObject*.
template<typename ... Args> PyObject* cpptuple2pytuple(const std::tuple<Args...>& t)
{
 cpptuple2pytuple_wrapper<Args...> wrapper(t);
 boost::python::tuple bpt = wrapper.delayed_dispatch();
 return boost::python::incref(boost::python::object(bpt).ptr());
}
// Convert (Python) tuple to (C++) tuple.
template<typename ... Args> std::tuple<Args...> pytuple2cpptuple(PyObject* obj)
{
 boost::python::tuple tup(boost::python::borrowed(obj));
 pytuple2cpptuple_wrapper<Args...> wrapper(tup);
 std::tuple<Args...> bpt = wrapper.delayed_dispatch();
 return bpt;
}
template<typename ... Args>
struct cpptuple_to_python_tuple
{
 static PyObject* convert(const std::tuple<Args...>& t)
 {
 return cpptuple2pytuple<Args...>(t);
 }
};
template<typename ... Args>
struct cpptuple_from_python_tuple
{
 cpptuple_from_python_tuple()
 {
 boost::python::converter::registry::push_back(
 &convertible,
 &construct,
 boost::python::type_id<std::tuple<Args...> >());
 }
 static void* convertible(PyObject* obj_ptr)
 {
 if (!PyTuple_CheckExact(obj_ptr)) return 0;
 return obj_ptr;
 }
 static void construct(
 PyObject* obj_ptr,
 boost::python::converter::rvalue_from_python_stage1_data* data)
 {
 void* storage = (
 (boost::python::converter::rvalue_from_python_storage<std::tuple<Args...> >*)
 data)->storage.bytes;
 new (storage) std::tuple<Args...>(pytuple2cpptuple<Args...>(obj_ptr));
 data->convertible = storage;
 }
};
template<typename ...Args> void create_tuple_converter()
{
 boost::python::to_python_converter<std::tuple<Args...>, cpptuple_to_python_tuple<Args...> >();
 cpptuple_from_python_tuple<Args...>();
}
void export_cpptuple_conv()
{
 create_tuple_converter<int, float>();
 create_tuple_converter<int, double, string>();
}
std::tuple<int, float> tupid1(std::tuple<int, float> t){return t;}
std::tuple<int, double, string> tupid2(std::tuple<int, double, string> t){return t;}
BOOST_PYTHON_MODULE(bptuple)
{
 export_cpptuple_conv();
 boost::python::def("tupid1", tupid1);
 boost::python::def("tupid2", tupid2);
}
###################################################
SConstruct
###################################################
#!/usr/bin/python
import commands, glob, os
def pyversion():
 pystr = commands.getoutput('python -V')
 version = pystr.split(' ')[1]
 major, minor = version.split('.')[:2]
 return major + '.' + minor
boost_python_env = Environment(
 #CXX="g++",
 CXX="g++-4.7",
 CPPPATH=["/usr/include/python"+pyversion()],
 CXXFLAGS="-ftemplate-depth-100 -fno-strict-aliasing -ansi -Wextra -Wall -Werror -Wno-unused-function -g -O3 -std=c++11",
 CPPDEFINES=['BOOST_PYTHON_DYNAMIC_LIB'],
 LIBPATH=["/usr/lib/python"+pyversion()+"/config"],
 LIBS=["python"+pyversion(), "m", "boost_python"],
 SHLIBPREFIX="", #gets rid of lib prefix
 )
boost_python_env.SharedLibrary(target="bptuple", source=["cpptup_conv_pif.cpp"])
###################################################

cpptup_conv_pif.cpp

#include <tuple>
#include <string>
#include <iostream>
using std::cout;
using std::endl;
using std::string;
#include <boost/python/tuple.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/object.hpp>
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/def.hpp>
using boost::python::extract;
template<int ...> struct seq{};
template<int N, int ...S> struct gens : gens<N-1, N-1, S...>{};
template<int ...S> struct gens<0, S...> {typedef seq<S...> type;};
template <typename ...Args>
struct cpptuple2pytuple_wrapper
{
 std::tuple<Args...> params;
 cpptuple2pytuple_wrapper(const std::tuple<Args...>& _params):params(_params){}
 boost::python::tuple delayed_dispatch()
 {
 return callFunc(typename gens<sizeof...(Args)>::type());
 }
 template<int ...S>
 boost::python::tuple callFunc(seq<S...>)
 {
 return boost::python::make_tuple(std::get<S>(params) ...);
 }
};
template <typename ...Args>
struct pytuple2cpptuple_wrapper
{
 boost::python::tuple params;
 pytuple2cpptuple_wrapper(const boost::python::tuple& _params):params(_params){}
 std::tuple<Args...> delayed_dispatch()
 {
 return callFunc(typename gens<sizeof...(Args)>::type());
 }
 template<int ...S>
 std::tuple<Args...> callFunc(seq<S...>)
 {
 return std::make_tuple((static_cast<Args>(extract<Args>(params[S])))...);
 }
};
// Convert (C++) tuple to (Python) tuple as PyObject*.
template<typename ... Args> PyObject* cpptuple2pytuple(const std::tuple<Args...>& t)
{
 cpptuple2pytuple_wrapper<Args...> wrapper(t);
 boost::python::tuple bpt = wrapper.delayed_dispatch();
 return boost::python::incref(boost::python::object(bpt).ptr());
}
// Convert (Python) tuple to (C++) tuple.
template<typename ... Args> std::tuple<Args...> pytuple2cpptuple(PyObject* obj)
{
 boost::python::tuple tup(boost::python::borrowed(obj));
 pytuple2cpptuple_wrapper<Args...> wrapper(tup);
 std::tuple<Args...> bpt = wrapper.delayed_dispatch();
 return bpt;
}
template<typename ... Args>
struct cpptuple_to_python_tuple
{
 static PyObject* convert(const std::tuple<Args...>& t)
 {
 return cpptuple2pytuple<Args...>(t);
 }
};
template<typename ... Args>
struct cpptuple_from_python_tuple
{
 cpptuple_from_python_tuple()
 {
 boost::python::converter::registry::push_back(
 &convertible,
 &construct,
 boost::python::type_id<std::tuple<Args...> >());
 }
 static void* convertible(PyObject* obj_ptr)
 {
 if (!PyTuple_CheckExact(obj_ptr)) return 0;
 return obj_ptr;
 }
 static void construct(
 PyObject* obj_ptr,
 boost::python::converter::rvalue_from_python_stage1_data* data)
 {
 void* storage = (
 (boost::python::converter::rvalue_from_python_storage<std::tuple<Args...> >*)
 data)->storage.bytes;
 new (storage) std::tuple<Args...>(pytuple2cpptuple<Args...>(obj_ptr));
 data->convertible = storage;
 }
};
template<typename ...Args> void create_tuple_converter()
{
 boost::python::to_python_converter<std::tuple<Args...>, cpptuple_to_python_tuple<Args...> >();
 cpptuple_from_python_tuple<Args...>();
}
void export_cpptuple_conv()
{
 create_tuple_converter<int, float>();
 create_tuple_converter<int, double, string>();
}
std::tuple<int, float> tupid1(std::tuple<int, float> t){return t;}
std::tuple<int, double, string> tupid2(std::tuple<int, double, string> t){return t;}
BOOST_PYTHON_MODULE(bptuple)
{
 export_cpptuple_conv();
 boost::python::def("tupid1", tupid1);
 boost::python::def("tupid2", tupid2);
}

SConstruct

#!/usr/bin/python
import commands, glob, os
def pyversion():
 pystr = commands.getoutput('python -V')
 version = pystr.split(' ')[1]
 major, minor = version.split('.')[:2]
 return major + '.' + minor
boost_python_env = Environment(
 #CXX="g++",
 CXX="g++-4.7",
 CPPPATH=["/usr/include/python"+pyversion()],
 CXXFLAGS="-ftemplate-depth-100 -fno-strict-aliasing -ansi -Wextra -Wall -Werror -Wno-unused-function -g -O3 -std=c++11",
 CPPDEFINES=['BOOST_PYTHON_DYNAMIC_LIB'],
 LIBPATH=["/usr/lib/python"+pyversion()+"/config"],
 LIBS=["python"+pyversion(), "m", "boost_python"],
 SHLIBPREFIX="", #gets rid of lib prefix
 )
boost_python_env.SharedLibrary(target="bptuple", source=["cpptup_conv_pif.cpp"])
deleted 18 characters in body
Source Link
###################################################
SConstruct
###################################################
#!/usr/bin/python
import commands, glob, os
def pyversion():
 pystr = commands.getoutput('python -V')
 version = pystr.split(' ')[1]
 major, minor = version.split('.')[:2]
 return major + '.' + minor
boost_python_env = Environment(
 #CXX="g++",
 CXX="g++-4.7",
 CPPPATH=["/usr/include/python"+pyversion()],
 CXXFLAGS="-ftemplate-depth-100 -fno-strict-aliasing -ansi -Wextra -Wall -Werror -Wno-unused-function -g -O3 -std=c++11",
 CPPDEFINES=['BOOST_PYTHON_DYNAMIC_LIB'],
 LIBPATH=["/usr/lib/python"+pyversion()+"/config"],
 LIBS=["blitz", "Rmath", "python"+pyversionLIBS=["python"+pyversion(), "m", "boost_python"],
 SHLIBPREFIX="", #gets rid of lib prefix
 )
boost_python_env.SharedLibrary(target="bptuple", source=["cpptup_conv_pif.cpp"])
###################################################
###################################################
SConstruct
###################################################
#!/usr/bin/python
import commands, glob, os
def pyversion():
 pystr = commands.getoutput('python -V')
 version = pystr.split(' ')[1]
 major, minor = version.split('.')[:2]
 return major + '.' + minor
boost_python_env = Environment(
 #CXX="g++",
 CXX="g++-4.7",
 CPPPATH=["/usr/include/python"+pyversion()],
 CXXFLAGS="-ftemplate-depth-100 -fno-strict-aliasing -ansi -Wextra -Wall -Werror -Wno-unused-function -g -O3 -std=c++11",
 CPPDEFINES=['BOOST_PYTHON_DYNAMIC_LIB'],
 LIBPATH=["/usr/lib/python"+pyversion()+"/config"],
 LIBS=["blitz", "Rmath", "python"+pyversion(), "m", "boost_python"],
 SHLIBPREFIX="", #gets rid of lib prefix
 )
boost_python_env.SharedLibrary(target="bptuple", source=["cpptup_conv_pif.cpp"])
###################################################
###################################################
SConstruct
###################################################
#!/usr/bin/python
import commands, glob, os
def pyversion():
 pystr = commands.getoutput('python -V')
 version = pystr.split(' ')[1]
 major, minor = version.split('.')[:2]
 return major + '.' + minor
boost_python_env = Environment(
 #CXX="g++",
 CXX="g++-4.7",
 CPPPATH=["/usr/include/python"+pyversion()],
 CXXFLAGS="-ftemplate-depth-100 -fno-strict-aliasing -ansi -Wextra -Wall -Werror -Wno-unused-function -g -O3 -std=c++11",
 CPPDEFINES=['BOOST_PYTHON_DYNAMIC_LIB'],
 LIBPATH=["/usr/lib/python"+pyversion()+"/config"],
 LIBS=["python"+pyversion(), "m", "boost_python"],
 SHLIBPREFIX="", #gets rid of lib prefix
 )
boost_python_env.SharedLibrary(target="bptuple", source=["cpptup_conv_pif.cpp"])
###################################################
added 54 characters in body
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238
Loading
Tweeted twitter.com/#!/StackCodeReview/status/547784662333267968
Notice added Draw attention by Phrancis
Bounty Started worth 200 reputation by Phrancis
deleted 28 characters in body; edited tags
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238
Loading
edited tags; edited title
Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238
Loading
Post Migrated Here from stackoverflow.com (revisions)
Source Link
Loading
lang-cpp

AltStyle によって変換されたページ (->オリジナル) /