-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
985 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Copyright 2018 Dolphin Emulator Project | ||
// Licensed under GPLv2+ | ||
// Refer to the license.txt file included. | ||
|
||
#pragma once | ||
|
||
#include <tuple> | ||
|
||
template <class F, typename Tuple, size_t... Is> | ||
auto _TupleMapImpl(Tuple& t, F f, std::index_sequence<Is...>) | ||
{ | ||
return std::make_tuple(f(std::get<Is>(t))...); | ||
} | ||
|
||
// returns a new tuple with each tuple item mapped by the given function. | ||
// The tuple is passed by reference, so the mapping function may take references to the values. | ||
template <class F, typename... Args> | ||
auto TupleMap(std::tuple<Args...>& t, F f) | ||
{ | ||
return _TupleMapImpl(t, f, std::make_index_sequence<sizeof...(Args)>{}); | ||
} | ||
|
||
|
||
template <typename Tuple, size_t... Is> | ||
static auto _TupleToArrayImpl(Tuple& t, std::index_sequence<Is...>) | ||
{ | ||
return std::array<std::tuple_element_t<0, Tuple>, sizeof...(Is)>{std::get<Is>(t)...}; | ||
} | ||
|
||
// turns a tuple consisting of 1 or more elements of the same type into a std::array | ||
template <typename... Args> | ||
static auto TupleToArray(std::tuple<Args...>& t) | ||
{ | ||
return _TupleToArrayImpl(t, std::make_index_sequence<sizeof...(Args)>{}); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// Copyright 2018 Dolphin Emulator Project | ||
// Licensed under GPLv2+ | ||
// Refer to the license.txt file included. | ||
|
||
#pragma once | ||
|
||
#include <Python.h> | ||
#include <tuple> | ||
#include <iostream> | ||
|
||
#include "Common/TupleUtil.h" | ||
|
||
#include "Scripting/Python/PyFramework/fmt.h" | ||
|
||
|
||
namespace Py | ||
{ | ||
|
||
|
||
template <typename TRet, typename... TsArgs> | ||
using Fun = TRet (*)(TsArgs...); | ||
|
||
template <typename T, T> | ||
struct WrapHelper; | ||
|
||
template <typename TRet, typename... TsArgs, Fun<TRet, TsArgs...> TFun> | ||
struct WrapHelper<Fun<TRet, TsArgs...>, TFun> | ||
{ | ||
static PyObject* func(PyObject* self, PyObject* args) | ||
{ | ||
std::tuple<TsArgs...> args_tpl; | ||
|
||
std::tuple<PyObject*, const char*> py_args_and_fmt = | ||
std::make_tuple(args, Py::fmts<TsArgs...>.c_str()); | ||
std::tuple<const TsArgs*...> args_pointers = | ||
TupleMap(args_tpl, [](const auto& obj) { return &obj; }); | ||
auto invoke_args = std::tuple_cat(py_args_and_fmt, args_pointers); | ||
if (!std::apply(PyArg_ParseTuple, invoke_args)) | ||
return nullptr; | ||
|
||
if constexpr (std::is_same_v<TRet, void>) | ||
{ | ||
std::apply(TFun, args_tpl); | ||
Py_RETURN_NONE; | ||
} | ||
else | ||
{ | ||
TRet result = std::apply(TFun, args_tpl); | ||
return Py_BuildValue(Py::fmt<TRet>, result); | ||
} | ||
|
||
} | ||
}; | ||
|
||
template <auto T> | ||
struct Wrap : WrapHelper<decltype(T), T> | ||
{ | ||
}; | ||
|
||
template <auto T> | ||
static PyCFunction as_py_function = Wrap<T>::func; | ||
|
||
|
||
} // namespace Py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
// Copyright 2018 Dolphin Emulator Project | ||
// Licensed under GPLv2+ | ||
// Refer to the license.txt file included. | ||
|
||
#pragma once | ||
|
||
#include <Python.h> | ||
#include <string> | ||
|
||
|
||
namespace Py | ||
{ | ||
|
||
|
||
// translates types to format strings according to the documentation: | ||
// https://docs.python.org/3/c-api/arg.html | ||
template <typename T> | ||
constexpr const char* GetPyFmt() | ||
{ | ||
static_assert(sizeof(T) != sizeof(T), "no python format string known for given type"); | ||
return nullptr; | ||
} | ||
#pragma region template specializations for each type | ||
template <> | ||
constexpr const char* GetPyFmt<signed char>() | ||
{ | ||
return "b"; | ||
} | ||
template <> | ||
constexpr const char* GetPyFmt<signed short>() | ||
{ | ||
return "h"; | ||
} | ||
template <> | ||
constexpr const char* GetPyFmt<signed int>() | ||
{ | ||
return "i"; | ||
} | ||
template <> | ||
constexpr const char* GetPyFmt<signed long>() | ||
{ | ||
return "l"; | ||
} | ||
template <> | ||
constexpr const char* GetPyFmt<signed long long>() | ||
{ | ||
return "L"; | ||
} | ||
template <> | ||
constexpr const char* GetPyFmt<unsigned char>() | ||
{ | ||
return "B"; | ||
} | ||
template <> | ||
constexpr const char* GetPyFmt<unsigned short>() | ||
{ | ||
return "H"; | ||
} | ||
template <> | ||
constexpr const char* GetPyFmt<unsigned int>() | ||
{ | ||
return "I"; | ||
} | ||
template <> | ||
constexpr const char* GetPyFmt<unsigned long>() | ||
{ | ||
return "k"; | ||
} | ||
template <> | ||
constexpr const char* GetPyFmt<unsigned long long>() | ||
{ | ||
return "K"; | ||
} | ||
template <> | ||
constexpr const char* GetPyFmt<float>() | ||
{ | ||
return "f"; | ||
} | ||
template <> | ||
constexpr const char* GetPyFmt<double>() | ||
{ | ||
return "d"; | ||
} | ||
template <> | ||
constexpr const char* GetPyFmt<PyObject*>() | ||
{ | ||
return "O"; | ||
} | ||
template <> | ||
constexpr const char* GetPyFmt<char*>() | ||
{ | ||
return "s"; | ||
} | ||
#pragma endregion | ||
|
||
template <typename T> | ||
constexpr const char* fmt = GetPyFmt<T>(); | ||
|
||
template <typename TLast> | ||
std::string GetPyFmts() | ||
{ | ||
return std::string{fmt<TLast>}; | ||
} | ||
|
||
template <typename TFirst, typename TSecond, typename... TRest> | ||
std::string GetPyFmts() | ||
{ | ||
return fmt<TFirst> + GetPyFmts<TSecond, TRest...>(); | ||
} | ||
|
||
template <typename... Ts> | ||
const std::string fmts = GetPyFmts<Ts...>(); | ||
|
||
|
||
} // namespace Py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright 2018 Dolphin Emulator Project | ||
// Licensed under GPLv2+ | ||
// Refer to the license.txt file included. | ||
|
||
#pragma once | ||
|
||
#include <Python.h> | ||
#include "Scripting/Python/PyFramework/as_py_function.h" | ||
|
||
namespace Py | ||
{ | ||
|
||
|
||
/*template <typename T> | ||
struct FuncDef | ||
{ | ||
char* func_name; | ||
T func; | ||
};*/ | ||
|
||
template <auto func> | ||
constexpr PyMethodDef MakeMethodDef(const char* name) | ||
{ | ||
const auto x = as_py_function<func>; | ||
return {name, x, METH_VARARGS, ""}; | ||
} | ||
|
||
/*constexpr PyModuleDef MakeModule(const char* module_name, PyMethodDef func_defs[]) | ||
{ | ||
return {PyModuleDef_HEAD_INIT, module_name, nullptr, -1, func_defs}; | ||
}*/ | ||
|
||
/*template <typename... Ts> | ||
PyModuleDef MakeModule(const char* module_name, FuncDef<Ts>... func_defs) | ||
{ | ||
std::tuple<decltype(func_defs)...> func_tpl{func_defs...}; | ||
auto py_funcs_tpl = TupleMap(func_tpl, [](auto& x) { | ||
return {x.func_name, as_py_function<x.func>, METH_VARARGS, ""}; | ||
}); | ||
std::array<PyMethodDef, sizeof...(func_defs)> py_funcs = TupleToArray(py_funcs_tpl); | ||
PyMethodDef Methods[] = {py_funcs}; | ||
return {PyModuleDef_HEAD_INIT, module_name, nullptr, -1, Methods}; | ||
}*/ | ||
|
||
|
||
} // namespace Py |
Oops, something went wrong.