blob: f82e41f0aac0540225add9a571c9c711dbe4bce2 [file] [log] [blame]
Stefan Krah39042e02020-08-10 16:32:21 +02001/*
2 * Copyright (c) 2020 Stefan Krah. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28
29#ifndef CPYTHON_DECIMAL_H_
30#define CPYTHON_DECIMAL_H_
31
32
33#include <Python.h>
34
35#ifdef __cplusplus
36extern "C" {
37#endif
38
39/****************************************************************************/
40/* Libmpdec API */
41/****************************************************************************/
42
43#ifndef LIBMPDEC_MPDECIMAL_H_
44struct mpd_t; /* ABI-stable in the libmpdec-2.x series */
45
46/* status cases for getting a triple */
47enum mpd_triple_class {
48 MPD_TRIPLE_NORMAL,
49 MPD_TRIPLE_INF,
50 MPD_TRIPLE_QNAN,
51 MPD_TRIPLE_SNAN,
52 MPD_TRIPLE_ERROR,
53};
54
55typedef struct {
56 enum mpd_triple_class tag;
57 uint8_t sign;
58 uint64_t hi;
59 uint64_t lo;
60 int64_t exp;
61} mpd_uint128_triple_t;
62#endif
63
64
65/****************************************************************************/
66/* Capsule API */
67/****************************************************************************/
68
Erlend Egeberg Aaslandfe9f4462021-01-06 12:47:28 +010069#define PyDec_CAPSULE_NAME "_decimal._API"
70
Stefan Krah39042e02020-08-10 16:32:21 +020071/* Simple API */
72#define PyDec_TypeCheck_INDEX 0
73#define PyDec_TypeCheck_RETURN int
74#define PyDec_TypeCheck_ARGS (const PyObject *)
75
76#define PyDec_IsSpecial_INDEX 1
77#define PyDec_IsSpecial_RETURN int
78#define PyDec_IsSpecial_ARGS (const PyObject *)
79
80#define PyDec_IsNaN_INDEX 2
81#define PyDec_IsNaN_RETURN int
82#define PyDec_IsNaN_ARGS (const PyObject *)
83
84#define PyDec_IsInfinite_INDEX 3
85#define PyDec_IsInfinite_RETURN int
86#define PyDec_IsInfinite_ARGS (const PyObject *)
87
88#define PyDec_GetDigits_INDEX 4
89#define PyDec_GetDigits_RETURN int64_t
90#define PyDec_GetDigits_ARGS (const PyObject *)
91
92#define PyDec_AsUint128Triple_INDEX 5
93#define PyDec_AsUint128Triple_RETURN mpd_uint128_triple_t
94#define PyDec_AsUint128Triple_ARGS (const PyObject *)
95
96#define PyDec_FromUint128Triple_INDEX 6
97#define PyDec_FromUint128Triple_RETURN PyObject *
98#define PyDec_FromUint128Triple_ARGS (const mpd_uint128_triple_t *triple)
99
100/* Advanced API */
101#define PyDec_Alloc_INDEX 7
102#define PyDec_Alloc_RETURN PyObject *
103#define PyDec_Alloc_ARGS (void)
104
105#define PyDec_Get_INDEX 8
106#define PyDec_Get_RETURN mpd_t *
107#define PyDec_Get_ARGS (PyObject *)
108
109#define PyDec_GetConst_INDEX 9
110#define PyDec_GetConst_RETURN const mpd_t *
111#define PyDec_GetConst_ARGS (const PyObject *)
112
113#define CPYTHON_DECIMAL_MAX_API 10
114
115
116#ifdef CPYTHON_DECIMAL_MODULE
117/* Simple API */
118static PyDec_TypeCheck_RETURN PyDec_TypeCheck PyDec_TypeCheck_ARGS;
119static PyDec_IsSpecial_RETURN PyDec_IsSpecial PyDec_IsSpecial_ARGS;
120static PyDec_IsNaN_RETURN PyDec_IsNaN PyDec_IsNaN_ARGS;
121static PyDec_IsInfinite_RETURN PyDec_IsInfinite PyDec_IsInfinite_ARGS;
122static PyDec_GetDigits_RETURN PyDec_GetDigits PyDec_GetDigits_ARGS;
123static PyDec_AsUint128Triple_RETURN PyDec_AsUint128Triple PyDec_AsUint128Triple_ARGS;
124static PyDec_FromUint128Triple_RETURN PyDec_FromUint128Triple PyDec_FromUint128Triple_ARGS;
125
126/* Advanced API */
127static PyDec_Alloc_RETURN PyDec_Alloc PyDec_Alloc_ARGS;
128static PyDec_Get_RETURN PyDec_Get PyDec_Get_ARGS;
129static PyDec_GetConst_RETURN PyDec_GetConst PyDec_GetConst_ARGS;
130#else
131static void **_decimal_api;
132
133/* Simple API */
134#define PyDec_TypeCheck \
135 (*(PyDec_TypeCheck_RETURN (*)PyDec_TypeCheck_ARGS) _decimal_api[PyDec_TypeCheck_INDEX])
136
137#define PyDec_IsSpecial \
138 (*(PyDec_IsSpecial_RETURN (*)PyDec_IsSpecial_ARGS) _decimal_api[PyDec_IsSpecial_INDEX])
139
140#define PyDec_IsNaN \
141 (*(PyDec_IsNaN_RETURN (*)PyDec_IsNaN_ARGS) _decimal_api[PyDec_IsNaN_INDEX])
142
143#define PyDec_IsInfinite \
144 (*(PyDec_IsInfinite_RETURN (*)PyDec_IsInfinite_ARGS) _decimal_api[PyDec_IsInfinite_INDEX])
145
146#define PyDec_GetDigits \
147 (*(PyDec_GetDigits_RETURN (*)PyDec_GetDigits_ARGS) _decimal_api[PyDec_GetDigits_INDEX])
148
149#define PyDec_AsUint128Triple \
150 (*(PyDec_AsUint128Triple_RETURN (*)PyDec_AsUint128Triple_ARGS) _decimal_api[PyDec_AsUint128Triple_INDEX])
151
152#define PyDec_FromUint128Triple \
153 (*(PyDec_FromUint128Triple_RETURN (*)PyDec_FromUint128Triple_ARGS) _decimal_api[PyDec_FromUint128Triple_INDEX])
154
155/* Advanced API */
156#define PyDec_Alloc \
157 (*(PyDec_Alloc_RETURN (*)PyDec_Alloc_ARGS) _decimal_api[PyDec_Alloc_INDEX])
158
159#define PyDec_Get \
160 (*(PyDec_Get_RETURN (*)PyDec_Get_ARGS) _decimal_api[PyDec_Get_INDEX])
161
162#define PyDec_GetConst \
163 (*(PyDec_GetConst_RETURN (*)PyDec_GetConst_ARGS) _decimal_api[PyDec_GetConst_INDEX])
164
165
166static int
167import_decimal(void)
168{
Erlend Egeberg Aaslandfe9f4462021-01-06 12:47:28 +0100169 _decimal_api = (void **)PyCapsule_Import(PyDec_CAPSULE_NAME, 0);
Stefan Krah39042e02020-08-10 16:32:21 +0200170 if (_decimal_api == NULL) {
171 return -1;
172 }
173
174 return 0;
175}
176#endif
177
178#ifdef __cplusplus
179}
180#endif
181
182#endif /* CPYTHON_DECIMAL_H_ */