forked from APrioriInvestments/typed_python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPyStringInstance.hpp
More file actions
84 lines (69 loc) · 3.18 KB
/
Copy pathPyStringInstance.hpp
File metadata and controls
84 lines (69 loc) · 3.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#pragma once
#include "PyInstance.hpp"
class PyStringInstance : public PyInstance {
public:
typedef String modeled_type;
static void copyConstructFromPythonInstanceConcrete(String* eltType, instance_ptr tgt, PyObject* pyRepresentation, bool isExplicit) {
if (PyUnicode_Check(pyRepresentation)) {
auto kind = PyUnicode_KIND(pyRepresentation);
assert(
kind == PyUnicode_1BYTE_KIND ||
kind == PyUnicode_2BYTE_KIND ||
kind == PyUnicode_4BYTE_KIND
);
String().constructor(
tgt,
kind == PyUnicode_1BYTE_KIND ? 1 :
kind == PyUnicode_2BYTE_KIND ? 2 :
4,
PyUnicode_GET_LENGTH(pyRepresentation),
kind == PyUnicode_1BYTE_KIND ? (const char*)PyUnicode_1BYTE_DATA(pyRepresentation) :
kind == PyUnicode_2BYTE_KIND ? (const char*)PyUnicode_2BYTE_DATA(pyRepresentation) :
(const char*)PyUnicode_4BYTE_DATA(pyRepresentation)
);
return;
}
throw std::logic_error("Can't initialize a String from an instance of " +
std::string(pyRepresentation->ob_type->tp_name));
}
static bool pyValCouldBeOfTypeConcrete(modeled_type* type, PyObject* pyRepresentation) {
return PyUnicode_Check(pyRepresentation);
}
static PyObject* extractPythonObjectConcrete(String* t, instance_ptr data) {
int bytes_per_codepoint = String().bytes_per_codepoint(data);
return PyUnicode_FromKindAndData(
bytes_per_codepoint == 1 ? PyUnicode_1BYTE_KIND :
bytes_per_codepoint == 2 ? PyUnicode_2BYTE_KIND :
PyUnicode_4BYTE_KIND,
String().eltPtr(data, 0),
String().count(data)
);
}
static bool compare_to_python_concrete(String* t, instance_ptr self, PyObject* other, bool exact, int pyComparisonOp) {
if (!PyUnicode_Check(other)) {
return cmpResultToBoolForPyOrdering(pyComparisonOp, -1);
}
auto kind = PyUnicode_KIND(other);
int bytesPer = kind == PyUnicode_1BYTE_KIND ? 1 :
kind == PyUnicode_2BYTE_KIND ? 2 : 4;
if (bytesPer != t->bytes_per_codepoint(self)) {
return cmpResultToBoolForPyOrdering(pyComparisonOp, -1);
}
if (PyUnicode_GET_LENGTH(other) < t->count(self)) {
return cmpResultToBoolForPyOrdering(pyComparisonOp, -1);
}
if (PyUnicode_GET_LENGTH(other) > t->count(self)) {
return cmpResultToBoolForPyOrdering(pyComparisonOp, 1);
}
return cmpResultToBoolForPyOrdering(
pyComparisonOp,
memcmp(
kind == PyUnicode_1BYTE_KIND ? (const char*)PyUnicode_1BYTE_DATA(other) :
kind == PyUnicode_2BYTE_KIND ? (const char*)PyUnicode_2BYTE_DATA(other) :
(const char*)PyUnicode_4BYTE_DATA(other),
((String*)t)->eltPtr(self, 0),
PyUnicode_GET_LENGTH(other) * bytesPer
)
);
}
};