38 GILControl() : fSave(PyEval_SaveThread()) { }
40 PyEval_RestoreThread(fSave);
50#define CPPYY_IMPL_GILCALL(rtype, tcode) \
51static inline rtype GILCall##tcode( \
52 Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CPyCppyy::CallContext* ctxt)\
54 if (!ReleasesGIL(ctxt)) \
55 return Cppyy::Call##tcode(method, self, ctxt->GetSize(), ctxt->GetArgs());\
57 return Cppyy::Call##tcode(method, self, ctxt->GetSize(), ctxt->GetArgs());\
60#define CPPYY_IMPL_GILCALL(rtype, tcode) \
61static inline rtype GILCall##tcode( \
62 Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CPyCppyy::CallContext* ctxt)\
64 return Cppyy::Call##tcode(method, self, ctxt->GetSize(), ctxt->GetArgs());\
86 return Cppyy::CallO(method, self, ctxt->GetSize(), ctxt->GetArgs(), klass);
89 return Cppyy::CallO(method, self, ctxt->GetSize(), ctxt->GetArgs(), klass);
109 if (cl < -256 || cl > 255) {
110 PyErr_SetString(PyExc_ValueError,
"char conversion out of range");
122 PyErr_SetString(PyExc_ValueError,
"char conversion out of range");
144PyObject* CPyCppyy::BoolExecutor::Execute(
148 bool retval = GILCallB(method, self, ctxt);
149 PyObject* result = retval ? Py_True : Py_False;
155PyObject* CPyCppyy::BoolConstRefExecutor::Execute(
163PyObject* CPyCppyy::CharExecutor::Execute(
172PyObject* CPyCppyy::CharConstRefExecutor::Execute(
181PyObject* CPyCppyy::UCharExecutor::Execute(
190PyObject* CPyCppyy::UCharConstRefExecutor::Execute(
199PyObject* CPyCppyy::WCharExecutor::Execute(
204 wchar_t res = (wchar_t)GILCallL(method, self, ctxt);
205 return PyUnicode_FromWideChar(&res, 1);
209PyObject* CPyCppyy::Char16Executor::Execute(
214 char16_t res = (char16_t)GILCallL(method, self, ctxt);
215 return PyUnicode_DecodeUTF16((
const char*)&res,
sizeof(
char16_t),
nullptr,
nullptr);
219PyObject* CPyCppyy::Char32Executor::Execute(
224 char32_t res = (char32_t)GILCallL(method, self, ctxt);
225 return PyUnicode_DecodeUTF32((
const char*)&res,
sizeof(
char32_t),
nullptr,
nullptr);
229PyObject* CPyCppyy::IntExecutor::Execute(
237PyObject* CPyCppyy::Int8Executor::Execute(
245PyObject* CPyCppyy::UInt8Executor::Execute(
253PyObject* CPyCppyy::ShortExecutor::Execute(
261PyObject* CPyCppyy::LongExecutor::Execute(
265 return PyLong_FromLong((
Long_t)GILCallL(method, self, ctxt));
269PyObject* CPyCppyy::ULongExecutor::Execute(
273 return PyLong_FromUnsignedLong((
ULong_t)GILCallLL(method, self, ctxt));
277PyObject* CPyCppyy::LongLongExecutor::Execute(
281 Long64_t result = GILCallLL(method, self, ctxt);
282 return PyLong_FromLongLong(result);
286PyObject* CPyCppyy::ULongLongExecutor::Execute(
291 return PyLong_FromUnsignedLongLong(result);
295PyObject* CPyCppyy::FloatExecutor::Execute(
303PyObject* CPyCppyy::DoubleExecutor::Execute(
311PyObject* CPyCppyy::LongDoubleExecutor::Execute(
324 fAssignable = pyobject;
328 fAssignable =
nullptr;
333#define CPPYY_IMPL_REFEXEC(name, type, stype, F1, F2) \
334PyObject* CPyCppyy::name##RefExecutor::Execute( \
335 Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CallContext* ctxt) \
337 type* ref = (type*)GILCallR(method, self, ctxt); \
339 PyErr_SetString(PyExc_ReferenceError, "attempt to access a null-pointer");\
343 return F1((stype)*ref); \
345 *ref = (type)F2(fAssignable); \
346 Py_DECREF(fAssignable); \
347 fAssignable = nullptr; \
348 if (*ref == (type)-1 && PyErr_Occurred()) \
350 Py_INCREF(Py_None); \
374 return PyComplex_FromDoubles(
c.real(),
c.imag());
379 Py_complex cplx = PyComplex_AsCComplex(pycplx);
380 return std::complex<T>(cplx.real, cplx.imag);
384 std::complex<double>, PyComplex_FromComplex<double>, PyComplex_AsComplex<double>)
388PyObject* CPyCppyy::STLStringRefExecutor::Execute(
392 std::string* result = (std::string*)GILCallR(method, self, ctxt);
396 *result = std::string(
399 Py_DECREF(fAssignable);
400 fAssignable =
nullptr;
406PyObject* CPyCppyy::VoidExecutor::Execute(
410 GILCallV(method, self, ctxt);
415PyObject* CPyCppyy::CStringExecutor::Execute(
419 char* result = (
char*)GILCallR(method, self, ctxt);
429PyObject* CPyCppyy::WCStringExecutor::Execute(
433 wchar_t* result = (
wchar_t*)GILCallR(method, self, ctxt);
436 return PyUnicode_FromWideChar(&w, 0);
439 return PyUnicode_FromWideChar(result, wcslen(result));
443PyObject* CPyCppyy::CString16Executor::Execute(
447 char16_t* result = (
char16_t*)GILCallR(method, self, ctxt);
450 return PyUnicode_DecodeUTF16((
const char*)&w, 0,
nullptr,
nullptr);
453 return PyUnicode_DecodeUTF16((
const char*)result,
454 std::char_traits<char16_t>::length(result)*
sizeof(
char16_t),
nullptr,
nullptr);
458PyObject* CPyCppyy::CString32Executor::Execute(
462 char32_t* result = (
char32_t*)GILCallR(method, self, ctxt);
465 return PyUnicode_DecodeUTF32((
const char*)&w, 0,
nullptr,
nullptr);
468 return PyUnicode_DecodeUTF32((
const char*)result,
469 std::char_traits<char32_t>::length(result)*
sizeof(
char32_t),
nullptr,
nullptr);
474PyObject* CPyCppyy::VoidArrayExecutor::Execute(
487#define CPPYY_IMPL_ARRAY_EXEC(name, type) \
488PyObject* CPyCppyy::name##ArrayExecutor::Execute( \
489 Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CallContext* ctxt) \
491 return CreateLowLevelView((type*)GILCallR(method, self, ctxt)); \
496#if __cplusplus > 201402L
516#define CPPYY_COMPLEX_EXEC(code, type) \
517PyObject* CPyCppyy::Complex##code##Executor::Execute( \
518 Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CallContext* ctxt) \
520 static Cppyy::TCppScope_t scopeid = Cppyy::GetScope("std::complex<"#type">");\
521 std::complex<type>* result = \
522 (std::complex<type>*)GILCallO(method, self, ctxt, scopeid); \
524 PyErr_SetString(PyExc_ValueError, "NULL result where temporary expected");\
528 PyObject* pyres = PyComplex_FromDoubles(result->real(), result->imag()); \
529 ::operator delete(result);
\
536PyObject* CPyCppyy::STLStringExecutor::Execute(
543 std::string* result = (std::string*)
GILCallO(method, self, ctxt, sSTLStringScope);
551 ::operator
delete(result);
557PyObject* CPyCppyy::STLWStringExecutor::Execute(
562 std::wstring* result = (std::wstring*)
GILCallO(method, self, ctxt, sSTLWStringScope);
565 return PyUnicode_FromWideChar(&w, 0);
568 PyObject* pyresult = PyUnicode_FromWideChar(result->c_str(), result->size());
569 ::operator
delete(result);
575PyObject* CPyCppyy::InstancePtrExecutor::Execute(
590PyObject* CPyCppyy::InstanceExecutor::Execute(
597 if (!PyErr_Occurred())
598 PyErr_SetString(PyExc_ValueError,
"nullptr result where temporary expected");
615 InstanceExecutor(klass)
622PyObject* CPyCppyy::InstanceRefExecutor::Execute(
627 if (!result || !fAssignable)
634 PyObject* descr = PyObject_Str(result);
636 PyErr_Format(PyExc_TypeError,
"cannot assign to return object (%s)",
639 PyErr_SetString(PyExc_TypeError,
"cannot assign to result");
643 Py_DECREF(fAssignable); fAssignable =
nullptr;
647 PyObject* res2 = PyObject_CallFunction(assign,
const_cast<char*
>(
"O"), fAssignable);
651 Py_DECREF(fAssignable); fAssignable =
nullptr;
664 PyObject* pystr = PyObject_Str(pyobj);
666 PyErr_Format(PyExc_TypeError,
670 PyErr_SetString(PyExc_TypeError,
"C++ object expected");
674PyObject* CPyCppyy::InstancePtrPtrExecutor::Execute(
682 void** result = (
void**)GILCallR(method, self, ctxt);
690 Py_DECREF(fAssignable);
691 fAssignable =
nullptr;
697PyObject* CPyCppyy::InstancePtrRefExecutor::Execute(
705 void** result = (
void**)GILCallR(method, self, ctxt);
712 Py_DECREF(fAssignable);
713 fAssignable =
nullptr;
720PyObject* CPyCppyy::InstanceArrayExecutor::Execute(
730PyObject* CPyCppyy::ConstructorExecutor::Execute(
739PyObject* CPyCppyy::PyObjectExecutor::Execute(
743 return (
PyObject*)GILCallR(method, self, ctxt);
761 return (
h->second)();
767 if (resolvedType != fullType) {
770 return (
h->second)();
774 bool isConst = strncmp(resolvedType.c_str(),
"const", 5) == 0;
781 return (
h->second)();
789 return (
h->second)();
796 return (
h->second)();
804 return new IteratorExecutor(klass);
808 result =
new InstanceExecutor(klass);
810 result =
new InstanceRefExecutor(klass);
811 else if (cpd ==
"**" || cpd ==
"*[]" || cpd ==
"&*")
812 result =
new InstancePtrPtrExecutor(klass);
813 else if (cpd ==
"*&")
814 result =
new InstancePtrRefExecutor(klass);
815 else if (cpd ==
"[]") {
818 result =
new InstanceArrayExecutor(klass, asize);
820 result =
new InstancePtrRefExecutor(klass);
822 result =
new InstancePtrExecutor(klass);
830 result = (
h->second)();
873 return GILCallR(meth, obj, ctxt);
882#define WSTRING "basic_string<wchar_t,char_traits<wchar_t>,allocator<wchar_t> >"
884struct InitExecFactories_t {
886 InitExecFactories_t() {
891 gf[
"bool"] = (
ef_t)+[]() {
static BoolExecutor
e{};
return &
e; };
892 gf[
"bool&"] = (
ef_t)+[]() {
return new BoolRefExecutor{}; };
893 gf[
"const bool&"] = (
ef_t)+[]() {
static BoolConstRefExecutor
e{};
return &
e; };
894 gf[
"char"] = (
ef_t)+[]() {
static CharExecutor
e{};
return &
e; };
895 gf[
"signed char"] = gf[
"char"];
896 gf[
"unsigned char"] = (
ef_t)+[]() {
static UCharExecutor
e{};
return &
e; };
897 gf[
"char&"] = (
ef_t)+[]() {
return new CharRefExecutor{}; };
898 gf[
"signed char&"] = gf[
"char&"];
899 gf[
"unsigned char&"] = (
ef_t)+[]() {
return new UCharRefExecutor{}; };
900 gf[
"const char&"] = (
ef_t)+[]() {
static CharConstRefExecutor
e{};
return &
e; };
901 gf[
"const signed char&"] = gf[
"const char&"];
902 gf[
"const unsigned char&"] = (
ef_t)+[]() {
static UCharConstRefExecutor
e{};
return &
e; };
903 gf[
"wchar_t"] = (
ef_t)+[]() {
static WCharExecutor
e{};
return &
e; };
904 gf[
"char16_t"] = (
ef_t)+[]() {
static Char16Executor
e{};
return &
e; };
905 gf[
"char32_t"] = (
ef_t)+[]() {
static Char32Executor
e{};
return &
e; };
906 gf[
"int8_t"] = (
ef_t)+[]() {
static Int8Executor
e{};
return &
e; };
907 gf[
"int8_t&"] = (
ef_t)+[]() {
return new Int8RefExecutor{}; };
908 gf[
"const int8_t&"] = (
ef_t)+[]() {
static Int8RefExecutor
e{};
return &
e; };
909 gf[
"uint8_t"] = (
ef_t)+[]() {
static UInt8Executor
e{};
return &
e; };
910 gf[
"uint8_t&"] = (
ef_t)+[]() {
return new UInt8RefExecutor{}; };
911 gf[
"const uint8_t&"] = (
ef_t)+[]() {
static UInt8RefExecutor
e{};
return &
e; };
912 gf[
"short"] = (
ef_t)+[]() {
static ShortExecutor
e{};
return &
e; };
913 gf[
"short&"] = (
ef_t)+[]() {
return new ShortRefExecutor{}; };
914 gf[
"int"] = (
ef_t)+[]() {
static IntExecutor
e{};
return &
e; };
915 gf[
"int&"] = (
ef_t)+[]() {
return new IntRefExecutor{}; };
916 gf[
"unsigned short"] = gf[
"int"];
917 gf[
"unsigned short&"] = (
ef_t)+[]() {
return new UShortRefExecutor{}; };
918 gf[
"unsigned long"] = (
ef_t)+[]() {
static ULongExecutor
e{};
return &
e; };
919 gf[
"unsigned long&"] = (
ef_t)+[]() {
return new ULongRefExecutor{}; };
920 gf[
"unsigned int"] = gf[
"unsigned long"];
921 gf[
"unsigned int&"] = (
ef_t)+[]() {
return new UIntRefExecutor{}; };
922 gf[
"long"] = (
ef_t)+[]() {
static LongExecutor
e{};
return &
e; };
923 gf[
"long&"] = (
ef_t)+[]() {
return new LongRefExecutor{}; };
924 gf[
"unsigned long"] = (
ef_t)+[]() {
static ULongExecutor
e{};
return &
e; };
925 gf[
"unsigned long&"] = (
ef_t)+[]() {
return new ULongRefExecutor{}; };
926 gf[
"long long"] = (
ef_t)+[]() {
static LongLongExecutor
e{};
return &
e; };
927 gf[
"long long&"] = (
ef_t)+[]() {
return new LongLongRefExecutor{}; };
928 gf[
"unsigned long long"] = (
ef_t)+[]() {
static ULongLongExecutor
e{};
return &
e; };
929 gf[
"unsigned long long&"] = (
ef_t)+[]() {
return new ULongLongRefExecutor{}; };
931 gf[
"float"] = (
ef_t)+[]() {
static FloatExecutor
e{};
return &
e; };
932 gf[
"float&"] = (
ef_t)+[]() {
return new FloatRefExecutor{}; };
933 gf[
"double"] = (
ef_t)+[]() {
static DoubleExecutor
e{};
return &
e; };
934 gf[
"double&"] = (
ef_t)+[]() {
return new DoubleRefExecutor{}; };
935 gf[
"long double"] = (
ef_t)+[]() {
static LongDoubleExecutor
e{};
return &
e; };
936 gf[
"long double&"] = (
ef_t)+[]() {
return new LongDoubleRefExecutor{}; };
937 gf[
"void"] = (
ef_t)+[]() {
static VoidExecutor
e{};
return &
e; };
940 gf[
"void*"] = (
ef_t)+[]() {
static VoidArrayExecutor
e{};
return &
e; };
941 gf[
"bool*"] = (
ef_t)+[]() {
static BoolArrayExecutor
e{};
return &
e; };
942 gf[
"unsigned char*"] = (
ef_t)+[]() {
static UCharArrayExecutor
e{};
return &
e; };
943 gf[
"const unsigned char*"] = gf[
"unsigned char*"];
944#if __cplusplus > 201402L
945 gf[
"byte*"] = (
ef_t)+[]() {
static ByteArrayExecutor
e{};
return &
e; };
946 gf[
"const byte*"] = gf[
"byte*"];
948 gf[
"short*"] = (
ef_t)+[]() {
static ShortArrayExecutor
e{};
return &
e; };
949 gf[
"unsigned short*"] = (
ef_t)+[]() {
static UShortArrayExecutor
e{};
return &
e; };
950 gf[
"int*"] = (
ef_t)+[]() {
static IntArrayExecutor
e{};
return &
e; };
951 gf[
"unsigned int*"] = (
ef_t)+[]() {
static UIntArrayExecutor
e{};
return &
e; };
952 gf[
"long*"] = (
ef_t)+[]() {
static LongArrayExecutor
e{};
return &
e; };
953 gf[
"unsigned long*"] = (
ef_t)+[]() {
static ULongArrayExecutor
e{};
return &
e; };
954 gf[
"long long*"] = (
ef_t)+[]() {
static LLongArrayExecutor
e{};
return &
e; };
955 gf[
"unsigned long long*"] = (
ef_t)+[]() {
static ULLongArrayExecutor
e{};
return &
e; };
956 gf[
"float*"] = (
ef_t)+[]() {
static FloatArrayExecutor
e{};
return &
e; };
957 gf[
"double*"] = (
ef_t)+[]() {
static DoubleArrayExecutor
e{};
return &
e; };
958 gf[
"complex<float>*"] = (
ef_t)+[]() {
static ComplexFArrayExecutor
e{};
return &
e; };
959 gf[
"complex<double>*"] = (
ef_t)+[]() {
static ComplexDArrayExecutor
e{};
return &
e; };
960 gf[
"complex<int>*"] = (
ef_t)+[]() {
static ComplexIArrayExecutor
e{};
return &
e; };
961 gf[
"complex<long>*"] = (
ef_t)+[]() {
static ComplexLArrayExecutor
e{};
return &
e; };
964 gf[
"internal_enum_type_t"] = gf[
"int"];
965 gf[
"internal_enum_type_t&"] = gf[
"int&"];
966 gf[
"internal_enum_type_t*"] = gf[
"int*"];
967#if __cplusplus > 201402L
968 gf[
"byte"] = gf[
"uint8_t"];
969 gf[
"byte&"] = gf[
"uint8_t&"];
970 gf[
"const byte&"] = gf[
"const uint8_t&"];
972 gf[
"Long64_t"] = gf[
"long long"];
973 gf[
"Long64_t&"] = gf[
"long long&"];
974 gf[
"Long64_t*"] = gf[
"long long*"];
975 gf[
"ULong64_t"] = gf[
"unsigned long long"];
976 gf[
"ULong64_t&"] = gf[
"unsigned long long&"];
977 gf[
"ULong64_t*"] = gf[
"unsigned long long*"];
978 gf[
"Float16_t"] = gf[
"float"];
979 gf[
"Float16_t&"] = gf[
"float&"];
980 gf[
"Double32_t"] = gf[
"double"];
981 gf[
"Double32_t&"] = gf[
"double&"];
984 gf[
"const char*"] = (
ef_t)+[]() {
static CStringExecutor
e{};
return &
e; };
985 gf[
"char*"] = gf[
"const char*"];
986 gf[
"const signed char*"] = gf[
"const char*"];
987 gf[
"signed char*"] = gf[
"char*"];
988 gf[
"wchar_t*"] = (
ef_t)+[]() {
static WCStringExecutor
e{};
return &
e;};
989 gf[
"char16_t*"] = (
ef_t)+[]() {
static CString16Executor
e{};
return &
e;};
990 gf[
"char32_t*"] = (
ef_t)+[]() {
static CString32Executor
e{};
return &
e;};
991 gf[
"std::string"] = (
ef_t)+[]() {
static STLStringExecutor
e{};
return &
e; };
992 gf[
"string"] = gf[
"std::string"];
993 gf[
"std::string&"] = (
ef_t)+[]() {
return new STLStringRefExecutor{}; };
994 gf[
"string&"] = gf[
"std::string&"];
995 gf[
"std::wstring"] = (
ef_t)+[]() {
static STLWStringExecutor
e{};
return &
e; };
996 gf[
"std::" WSTRING] = gf[
"std::wstring"];
997 gf[
WSTRING] = gf[
"std::wstring"];
998 gf[
"complex<double>"] = (
ef_t)+[]() {
static ComplexDExecutor
e{};
return &
e; };
999 gf[
"complex<double>&"] = (
ef_t)+[]() {
return new ComplexDRefExecutor{}; };
1000 gf[
"__init__"] = (
ef_t)+[]() {
static ConstructorExecutor
e{};
return &
e; };
1001 gf[
"PyObject*"] = (
ef_t)+[]() {
static PyObjectExecutor
e{};
return &
e; };
1002 gf[
"_object*"] = gf[
"PyObject*"];
1003 gf[
"FILE*"] = gf[
"void*"];
1005} initExecvFactories_;
#define CPyCppyy_PyText_FromStringAndSize
#define CPyCppyy_PyText_AsString
#define CPyCppyy_PyText_GET_SIZE
#define CPyCppyy_PyText_FromFormat
#define CPyCppyy_PyText_CheckExact
#define CPyCppyy_PyText_FromString
static PyObject * PyComplex_FromComplex(const std::complex< T > &c)
static PyObject * CPyCppyy_PyText_FromLong(long cl)
static PyObject * SetInstanceCheckError(PyObject *pyobj)
static std::complex< T > PyComplex_AsComplex(PyObject *pycplx)
static Cppyy::TCppObject_t GILCallO(Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, CPyCppyy::CallContext *ctxt, Cppyy::TCppType_t klass)
#define CPPYY_IMPL_GILCALL(rtype, tcode)
static Cppyy::TCppObject_t GILCallConstructor(Cppyy::TCppMethod_t method, Cppyy::TCppType_t klass, CPyCppyy::CallContext *ctxt)
#define CPPYY_COMPLEX_EXEC(code, type)
static PyObject * CPyCppyy_PyText_FromULong(unsigned long uc)
static PyObject * CPyCppyy_PyBool_FromLong(long b)
#define CPPYY_IMPL_REFEXEC(name, type, stype, F1, F2)
#define CPPYY_IMPL_ARRAY_EXEC(name, type)
unsigned long long ULong64_t
virtual bool SetAssignable(PyObject *)
std::string remove_const(const std::string &cppname)
std::string clean_type(const std::string &cppname, bool template_strip=true, bool const_strip=true)
Py_ssize_t ArraySize(const std::string &name)
const std::string Compound(const std::string &name)
Set of helper functions that are invoked from the pythonizors, on the Python side.
unsigned long PyLongOrInt_AsULong(PyObject *pyobject)
CPYCPPYY_EXTERN bool UnregisterExecutor(const std::string &name)
PyObject * CreatePointerView(void *ptr, size_t size=(size_t) -1)
PyObject * BindCppObjectNoCast(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, const unsigned flags=0)
CPYCPPYY_EXPORT void DestroyExecutor(Executor *p)
CPYCPPYY_EXTERN bool RegisterExecutor(const std::string &name, ExecutorFactory_t)
CPYCPPYY_EXTERN Executor * CreateExecutor(const std::string &name)
std::map< std::string, ef_t > ExecFactories_t
bool CPPInstance_Check(T *object)
PyObject * gNullPtrObject
static ExecFactories_t gExecFactories
std::set< std::string > gIteratorTypes
PyObject * BindCppObject(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, const unsigned flags=0)
CPYCPPYY_EXTERN void * CallVoidP(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, CallContext *)
ULong64_t PyLongOrInt_AsULong64(PyObject *pyobject)
bool ReleasesGIL(CallContext *ctxt)
PyObject * BindCppObjectArray(Cppyy::TCppObject_t address, Cppyy::TCppType_t klass, Py_ssize_t *dims)
RPY_EXPORTED TCppObject_t CallO(TCppMethod_t method, TCppObject_t self, size_t nargs, void *args, TCppType_t result_type)
RPY_EXPORTED std::string ResolveName(const std::string &cppitem_name)
RPY_EXPORTED TCppObject_t CallConstructor(TCppMethod_t method, TCppType_t type, size_t nargs, void *args)
RPY_EXPORTED TCppScope_t GetScope(const std::string &scope_name)
RooArgList L(Args_t &&... args)
Parameter * GetArgs(size_t sz)