]> git.proxmox.com Git - ceph.git/blame - ceph/src/pmdk/src/include/libpmemobj/types.h
import ceph 16.2.7
[ceph.git] / ceph / src / pmdk / src / include / libpmemobj / types.h
CommitLineData
a4b75251
TL
1/* SPDX-License-Identifier: BSD-3-Clause */
2/* Copyright 2014-2020, Intel Corporation */
3
4/*
5 * libpmemobj/types.h -- definitions of libpmemobj type-safe macros
6 */
7#ifndef LIBPMEMOBJ_TYPES_H
8#define LIBPMEMOBJ_TYPES_H 1
9
10#include <libpmemobj/base.h>
11
12#ifdef __cplusplus
13extern "C" {
14#endif
15
16#define TOID_NULL(t) ((TOID(t))OID_NULL)
17#define PMEMOBJ_MAX_LAYOUT ((size_t)1024)
18
19/*
20 * Type safety macros
21 */
22#if !(defined _MSC_VER || defined __clang__)
23
24#define TOID_ASSIGN(o, value)(\
25{\
26 (o).oid = value;\
27 (o); /* to avoid "error: statement with no effect" */\
28})
29
30#else /* _MSC_VER or __clang__ */
31
32#define TOID_ASSIGN(o, value) ((o).oid = value, (o))
33
34#endif
35
36#if (defined _MSC_VER && _MSC_VER < 1912)
37/*
38 * XXX - workaround for offsetof issue in VS 15.3,
39 * it has been fixed since Visual Studio 2017 Version 15.5
40 * (_MSC_VER == 1912)
41 */
42#ifdef PMEMOBJ_OFFSETOF_WA
43#ifdef _CRT_USE_BUILTIN_OFFSETOF
44#undef offsetof
45#define offsetof(s, m) ((size_t)&reinterpret_cast < char const volatile& > \
46((((s *)0)->m)))
47#endif
48#else
49#ifdef _CRT_USE_BUILTIN_OFFSETOF
50#error "Invalid definition of offsetof() macro - see: \
51https://developercommunity.visualstudio.com/content/problem/96174/\
52offsetof-macro-is-broken-for-nested-objects.html \
53Please upgrade your VS, fix offsetof as described under the link or define \
54PMEMOBJ_OFFSETOF_WA to enable workaround in libpmemobj.h"
55#endif
56#endif
57
58#endif /* _MSC_VER */
59
60#define TOID_EQUALS(lhs, rhs)\
61((lhs).oid.off == (rhs).oid.off &&\
62 (lhs).oid.pool_uuid_lo == (rhs).oid.pool_uuid_lo)
63
64/* type number of root object */
65#define POBJ_ROOT_TYPE_NUM 0
66#define _toid_struct
67#define _toid_union
68#define _toid_enum
69#define _POBJ_LAYOUT_REF(name) (sizeof(_pobj_layout_##name##_ref))
70
71/*
72 * Typed OID
73 */
74#define TOID(t)\
75union _toid_##t##_toid
76
77#ifdef __cplusplus
78#define _TOID_CONSTR(t)\
79_toid_##t##_toid()\
80{ }\
81_toid_##t##_toid(PMEMoid _oid) : oid(_oid)\
82{ }
83#else
84#define _TOID_CONSTR(t)
85#endif
86
87/*
88 * Declaration of typed OID
89 */
90#define _TOID_DECLARE(t, i)\
91typedef uint8_t _toid_##t##_toid_type_num[(i) + 1];\
92TOID(t)\
93{\
94 _TOID_CONSTR(t)\
95 PMEMoid oid;\
96 t *_type;\
97 _toid_##t##_toid_type_num *_type_num;\
98}
99
100/*
101 * Declaration of typed OID of an object
102 */
103#define TOID_DECLARE(t, i) _TOID_DECLARE(t, i)
104
105/*
106 * Declaration of typed OID of a root object
107 */
108#define TOID_DECLARE_ROOT(t) _TOID_DECLARE(t, POBJ_ROOT_TYPE_NUM)
109
110/*
111 * Type number of specified type
112 */
113#define TOID_TYPE_NUM(t) (sizeof(_toid_##t##_toid_type_num) - 1)
114
115/*
116 * Type number of object read from typed OID
117 */
118#define TOID_TYPE_NUM_OF(o) (sizeof(*(o)._type_num) - 1)
119
120/*
121 * NULL check
122 */
123#define TOID_IS_NULL(o) ((o).oid.off == 0)
124
125/*
126 * Validates whether type number stored in typed OID is the same
127 * as type number stored in object's metadata
128 */
129#define TOID_VALID(o) (TOID_TYPE_NUM_OF(o) == pmemobj_type_num((o).oid))
130
131/*
132 * Checks whether the object is of a given type
133 */
134#define OID_INSTANCEOF(o, t) (TOID_TYPE_NUM(t) == pmemobj_type_num(o))
135
136/*
137 * Begin of layout declaration
138 */
139#define POBJ_LAYOUT_BEGIN(name)\
140typedef uint8_t _pobj_layout_##name##_ref[__COUNTER__ + 1]
141
142/*
143 * End of layout declaration
144 */
145#define POBJ_LAYOUT_END(name)\
146typedef char _pobj_layout_##name##_cnt[__COUNTER__ + 1 -\
147_POBJ_LAYOUT_REF(name)];
148
149/*
150 * Number of types declared inside layout without the root object
151 */
152#define POBJ_LAYOUT_TYPES_NUM(name) (sizeof(_pobj_layout_##name##_cnt) - 1)
153
154/*
155 * Declaration of typed OID inside layout declaration
156 */
157#define POBJ_LAYOUT_TOID(name, t)\
158TOID_DECLARE(t, (__COUNTER__ + 1 - _POBJ_LAYOUT_REF(name)));
159
160/*
161 * Declaration of typed OID of root inside layout declaration
162 */
163#define POBJ_LAYOUT_ROOT(name, t)\
164TOID_DECLARE_ROOT(t);
165
166/*
167 * Name of declared layout
168 */
169#define POBJ_LAYOUT_NAME(name) #name
170
171#define TOID_TYPEOF(o) __typeof__(*(o)._type)
172
173#define TOID_OFFSETOF(o, field) offsetof(TOID_TYPEOF(o), field)
174
175/*
176 * XXX - DIRECT_RW and DIRECT_RO are not available when compiled using VC++
177 * as C code (/TC). Use /TP option.
178 */
179#ifndef _MSC_VER
180
181#define DIRECT_RW(o) (\
182{__typeof__(o) _o; _o._type = NULL; (void)_o;\
183(__typeof__(*(o)._type) *)pmemobj_direct((o).oid); })
184#define DIRECT_RO(o) ((const __typeof__(*(o)._type) *)pmemobj_direct((o).oid))
185
186#elif defined(__cplusplus)
187
188/*
189 * XXX - On Windows, these macros do not behave exactly the same as on Linux.
190 */
191#define DIRECT_RW(o) \
192 (reinterpret_cast < __typeof__((o)._type) > (pmemobj_direct((o).oid)))
193#define DIRECT_RO(o) \
194 (reinterpret_cast < const __typeof__((o)._type) > \
195 (pmemobj_direct((o).oid)))
196
197#endif /* (defined(_MSC_VER) || defined(__cplusplus)) */
198
199#define D_RW DIRECT_RW
200#define D_RO DIRECT_RO
201
202#ifdef __cplusplus
203}
204#endif
205#endif /* libpmemobj/types.h */