Skip to content

Commit 5834798

Browse files
committed
Reduce dependencies and document the remaining ones.
The main change here is that most portable-snippets modules no longer include a hard dependency on the exact-int module, falling back instead on including <stdint.h> if exact-int.h has not been included (or the relevant types have not been otherwise defined). This also allows more flexibility in the directory structure; most modules can now be placed side-by-side in a single directory instead of forcing people to replicate the structure used in the portable-snippets repository. I've also tried to provide documentation of dependencies in each module's README to make portable-snippets a bit more user-friendly.
1 parent db1bd71 commit 5834798

22 files changed

+253
-31
lines changed

atomic/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,12 @@ you may be interested in
4949
[TinyCThread](https://github.com/tinycthread/tinycthread/)), or you
5050
could try the [atomic_ops](https://github.com/ivmai/libatomic_ops/)
5151
package.
52+
53+
## Dependencies
54+
55+
To maximize portability you should #include the exact-int module
56+
before including atomic.h, but if you don't want to add the extra
57+
file to your project you can omit it and this module will simply rely
58+
on <stdint.h>. As an alternative you may define `psnip_int32_t`, and
59+
`psnip_int64_t` to appropriate values yourself before including
60+
atomic.h.

atomic/atomic.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,18 @@
4848
#if !defined(PSNIP_ATOMIC_H)
4949
#define PSNIP_ATOMIC_H
5050

51-
#if !defined(psnip_int64_t) || !defined(psnip_int32_t)
52-
# include "../exact-int/exact-int.h"
51+
/* For maximum portability include the exact-int module from
52+
portable snippets. */
53+
#if \
54+
!defined(psnip_int64_t) || \
55+
!defined(psnip_int32_t)
56+
# include <stdint.h>
57+
# if !defined(psnip_int64_t)
58+
# define psnip_int64_t int64_t
59+
# endif
60+
# if !defined(psnip_int32_t)
61+
# define psnip_int32_t int32_t
62+
# endif
5363
#endif
5464

5565
#if !defined(PSNIP_ATOMIC_STATIC_INLINE)

builtin/README.md

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@ which compiler is actually in use (*i.e.*, you can use `__builtin_ffs`
1919
directly in MSVC, or any other compiler, including GCC < 3.3).
2020

2121
If the compiler already has the builtin, the psnip function will
22-
simply be defined to that builtin. If the compiler does not have an
23-
implementation one will be provided using either a built-in/intrinsic
24-
the compiler *does* support (i.e., using an MSVC intrinsic to
25-
implement a GCC built-in), or a fully-portable pure C implementation.
22+
simply be defined to that builtin (*e.g.*,
23+
`#define psnip_builtin_clz __builtin_clz`). If the compiler does not
24+
have an implementation one will be provided using either a
25+
built-in/intrinsic the compiler *does* support (*e.g.*, using an MSVC
26+
intrinsic to implement a GCC built-in), inline assembly,
27+
architecture-specific functions, or a fully-portable pure C
28+
implementation.
2629

2730
For example, for GCC's `__builtin_ffs` builtin, we provide
2831
implementations which work everywhere (including versions of GCC prior
@@ -49,6 +52,23 @@ int __builtin_ffsll(long long);
4952
Note that these are often provided as macros, the prototypes are for
5053
documentation only.
5154

55+
## Dependencies
56+
57+
To maximize portability you should #include the exact-int module
58+
before including builtin.h, but if you don't want to add the extra
59+
file to your project you can omit it and this module will simply rely
60+
on <stdint.h>. As an alternative you may define the following macros
61+
to appropriate values yourself:
62+
63+
* `psnip_int8_t`
64+
* `psnip_uint8_t`
65+
* `psnip_int16_t`
66+
* `psnip_uint16_t`
67+
* `psnip_int32_t`
68+
* `psnip_uint32_t`
69+
* `psnip_int64_t`
70+
* `psnip_uint64_t`
71+
5272
## Implementation Status
5373

5474
Virtually every generic builtin we can implement has been implemented.
@@ -101,8 +121,9 @@ For overflow-safe integer operations (i.e., `__builtin_*_overflow`),
101121
use [safe-math.h](../safe-math).
102122

103123
For bswap/byteswap functions, you should really use
104-
[endian.h](../endian) which also handles endianness detection as well
105-
as providing easier to use APIs.
124+
[endian.h](../endian), which depends on this module and handles
125+
endianness detection as well as providing easier to use APIs which
126+
integrate endianness detection logic.
106127

107128
For SIMD intrinsics (SSE, AVX, NEON, etc.), take a look at the
108129
[SIMDe](https://github.com/nemequ/simde/) project.

builtin/builtin.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,38 @@
7474
# include <arm_acle.h>
7575
#endif
7676

77+
/* For maximum portability include the exact-int module from
78+
portable snippets. */
7779
#if \
7880
!defined(psnip_int64_t) || !defined(psnip_uint64_t) || \
7981
!defined(psnip_int32_t) || !defined(psnip_uint32_t) || \
8082
!defined(psnip_int16_t) || !defined(psnip_uint16_t) || \
8183
!defined(psnip_int8_t) || !defined(psnip_uint8_t)
82-
# include "../exact-int/exact-int.h"
84+
# include <stdint.h>
85+
# if !defined(psnip_int64_t)
86+
# define psnip_int64_t int64_t
87+
# endif
88+
# if !defined(psnip_uint64_t)
89+
# define psnip_uint64_t uint64_t
90+
# endif
91+
# if !defined(psnip_int32_t)
92+
# define psnip_int32_t int32_t
93+
# endif
94+
# if !defined(psnip_uint32_t)
95+
# define psnip_uint32_t uint32_t
96+
# endif
97+
# if !defined(psnip_int16_t)
98+
# define psnip_int16_t int16_t
99+
# endif
100+
# if !defined(psnip_uint16_t)
101+
# define psnip_uint16_t uint16_t
102+
# endif
103+
# if !defined(psnip_int8_t)
104+
# define psnip_int8_t int8_t
105+
# endif
106+
# if !defined(psnip_uint8_t)
107+
# define psnip_uint8_t uint8_t
108+
# endif
83109
#endif
84110

85111
#if defined(HEDLEY_LIKELY) && defined(HEDLEY_UNLIKELY)

clock/README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,13 @@ with GNU extensions (e.g., -std=c11 instead of -std=gnu11), POSIX
3232
extensions will not be enabled by default so you won't get to use the
3333
`clock_gettime` implementation; to avoid this, you can define
3434
`_POSIX_C_SOURCE` to `199309L` or greater prior to including
35-
`clock.h`, or just define `_GNU_SOURCE`.
35+
`clock.h`, or just define `_GNU_SOURCE`.
36+
37+
## Dependencies
38+
39+
To maximize portability you should #include the exact-int module
40+
before including clock.h, but if you don't want to add the extra
41+
file to your project you can omit it and this module will simply rely
42+
on <stdint.h>. As an alternative you may define `psnip_uint64_t`,
43+
`psnip_uint32_t`, `psnip_int64_t`, `psnip_int32_t` to an appropriate
44+
value yourself before including clock.h.

clock/clock.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,23 @@
1111
#if !defined(PSNIP_CLOCK_H)
1212
#define PSNIP_CLOCK_H
1313

14-
#if !defined(psnip_uint64_t)
15-
# include "../exact-int/exact-int.h"
14+
/* For maximum portability include the exact-int module from
15+
portable snippets. */
16+
#if !defined(psnip_uint64_t) || !defined(psnip_int32_t) || \
17+
!defined(psnip_uint32_t) || !defined(psnip_int32_t)
18+
# include <stdint.h>
19+
# if !defined(psnip_int64_t)
20+
# define psnip_int64_t int64_t
21+
# endif
22+
# if !defined(psnip_uint64_t)
23+
# define psnip_uint64_t uint64_t
24+
# endif
25+
# if !defined(psnip_int32_t)
26+
# define psnip_int32_t int32_t
27+
# endif
28+
# if !defined(psnip_uint32_t)
29+
# define psnip_uint32_t uint32_t
30+
# endif
1631
#endif
1732

1833
#if !defined(PSNIP_CLOCK_STATIC_INLINE)

cpu/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# CPU Information
2+
3+
This module provides an API for querying some CPU features, such as
4+
ISA extension support, that works across multiple architectures and
5+
platforms.
6+
7+
## Dependencies
8+
9+
This module requires the once portable-snippet module. If you do not
10+
include once.h before cpu.h, cpu.h will automatically include
11+
"../once/once.h". If you include once.h manually you are free to use
12+
whatever directory structure you like.
13+
14+
## Limitations
15+
16+
This code currently only supports x86/x86-64 and ARM.

cpu/cpu.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010

1111
#include "cpu.h"
1212

13-
#include "../once/once.h"
13+
#if !defined(PSNIP_ONCE__H)
14+
# include "../once/once.h"
15+
#endif
1416

1517
#include <assert.h>
1618

endian/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,17 @@ If you need (or prefer) to fall back on run-time detection,
3737
`PSNIP_ENDIAN_ORDER_RT` will evaluate to the same values
3838
(`PSNIP_ENDIAN_LITTLE` or `PSNIP_ENDIAN_BIG`). Note that the
3939
"run-time" detection will likely be optimized away by the compiler.
40+
41+
## Dependencies
42+
43+
To maximize portability you should #include the exact-int module
44+
before including endian.h, but if you don't want to add the extra
45+
file to your project you can omit it and this module will simply rely
46+
on <stdint.h>. As an alternative you may define `psnip_uint16_t`,
47+
`psnip_uint32_t`, and `psnip_uint64_t` to appropriate values yourself
48+
before including endian.h.
49+
50+
This module requires the builtin portable-snippet module. If you do
51+
not include builtin.h before endian.h, endian.h will automatically
52+
include "../builtin/builtin.h". If you include builtin.h manually you
53+
are free to use whatever directory structure you like.

endian/endian.h

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,25 @@
1111
#if !defined(PSNIP_ENDIAN_H)
1212
#define PSNIP_ENDIAN_H
1313

14-
#if !defined(psnip_uint16_t) || !defined(psnip_uint32_t) || !defined(psnip_uint64_t)
15-
# include "../exact-int/exact-int.h"
14+
/* For maximum portability include the exact-int module from
15+
portable snippets. */
16+
#if \
17+
!defined(psnip_uint64_t) || \
18+
!defined(psnip_uint32_t) || \
19+
!defined(psnip_uint16_t)
20+
# include <stdint.h>
21+
# if !defined(psnip_uint64_t)
22+
# define psnip_uint64_t uint64_t
23+
# endif
24+
# if !defined(psnip_uint32_t)
25+
# define psnip_uint32_t uint32_t
26+
# endif
27+
# if !defined(psnip_uint16_t)
28+
# define psnip_uint16_t uint16_t
29+
# endif
1630
#endif
1731

18-
#if \
19-
!defined(psnip_builtin_bswap16) || \
20-
!defined(psnip_builtin_bswap32) || \
21-
!defined(psnip_builtin_bswap64)
32+
#if !defined(PSNIP_BUILTIN_H)
2233
# include "../builtin/builtin.h"
2334
#endif
2435

exact-int/exact-int.h

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,38 @@
99
*
1010
* This header tries to define psnip_(u)int(8|16|32|64)_t to
1111
* appropriate types given your system. For most systems this means
12-
* including <stdint.h> and adding a few preprocessor definitions.
13-
*
14-
* If you prefer, you can define any necessary types yourself.
15-
* Snippets in this repository which rely on these types will not
16-
* attempt to include this header if you have already defined the
17-
* types it uses.
12+
* including <stdint.h> and adding a few preprocessor definitions, but
13+
* when that isn't an option things get a bit more complicated.
1814
*/
1915

2016
#if !defined(PSNIP_EXACT_INT_H)
2117
# define PSNIP_EXACT_INT_H
18+
19+
# if defined(psnip_int8_t)
20+
# undef psnip_int8_t
21+
# endif
22+
# if defined(psnip_uint8_t)
23+
# undef psnip_uint8_t
24+
# endif
25+
# if defined(psnip_int16_t)
26+
# undef psnip_int16_t
27+
# endif
28+
# if defined(psnip_uint16_t)
29+
# undef psnip_uint16_t
30+
# endif
31+
# if defined(psnip_int32_t)
32+
# undef psnip_int32_t
33+
# endif
34+
# if defined(psnip_uint32_t)
35+
# undef psnip_uint32_t
36+
# endif
37+
# if defined(psnip_int64_t)
38+
# undef psnip_int64_t
39+
# endif
40+
# if defined(psnip_uint64_t)
41+
# undef psnip_uint64_t
42+
# endif
43+
2244
# if !defined(PSNIP_EXACT_INT_HAVE_STDINT)
2345
# if defined(_STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
2446
# define PSNIP_EXACT_INT_HAVE_STDINT

random/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,17 @@ faster than the reproducible PRNG, we'll use it.
6868
Note that, even if the fast source is implemented using the same
6969
algorithm as the reproducible source (i.e., PGC with a 32-bit state),
7070
the fast source will *not* alter the state of the reproducible PRNG.
71+
72+
## Dependencies
73+
74+
This module requires the following portable-snippet modules:
75+
76+
* exact-int
77+
* atomic — for thread-safety
78+
* clock — for seeding
79+
* once — for thread-safety
80+
* cpu — to detect CPU-based PRNGs (*i.e.*, RdRand on Intel)
81+
82+
The code currently assumes the same directory structure as is used in
83+
the portable-snippets repository. Patches to allow other structures
84+
will be seriously considered.

safe-math/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,23 @@ mode since there was no standard way to implement them until C11.
140140
Even if you request emulation of the GCC builtins, we cannot provide
141141
the `__builtin_*_overflow_p` functions.
142142
143+
## Dependencies
144+
145+
To maximize portability you should #include the exact-int module
146+
before including safe-math.h, but if you don't want to add the extra
147+
file to your project you can omit it and this module will simply rely
148+
on <stdint.h>. As an alternative you may define the following macros
149+
to appropriate values yourself:
150+
151+
* `psnip_int8_t`
152+
* `psnip_uint8_t`
153+
* `psnip_int16_t`
154+
* `psnip_uint16_t`
155+
* `psnip_int32_t`
156+
* `psnip_uint32_t`
157+
* `psnip_int64_t`
158+
* `psnip_uint64_t`
159+
143160
# Alternatives
144161
145162
## C

safe-math/safe-math.h

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,39 @@
6565
#endif
6666

6767
#if !defined(PSNIP_SAFE_NO_FIXED)
68+
/* For maximum portability include the exact-int module from
69+
portable snippets. */
6870
# if \
69-
!defined(psnip_uint8_t) || !defined(psnip_int8_t) || \
70-
!defined(psnip_uint16_t) || !defined(psnip_int16_t) || \
71-
!defined(psnip_uint32_t) || !defined(psnip_int32_t) || \
72-
!defined(psnip_uint64_t) || !defined(psnip_int64_t)
73-
# include "../exact-int/exact-int.h"
74-
#endif
71+
!defined(psnip_int64_t) || !defined(psnip_uint64_t) || \
72+
!defined(psnip_int32_t) || !defined(psnip_uint32_t) || \
73+
!defined(psnip_int16_t) || !defined(psnip_uint16_t) || \
74+
!defined(psnip_int8_t) || !defined(psnip_uint8_t)
75+
# include <stdint.h>
76+
# if !defined(psnip_int64_t)
77+
# define psnip_int64_t int64_t
78+
# endif
79+
# if !defined(psnip_uint64_t)
80+
# define psnip_uint64_t uint64_t
81+
# endif
82+
# if !defined(psnip_int32_t)
83+
# define psnip_int32_t int32_t
84+
# endif
85+
# if !defined(psnip_uint32_t)
86+
# define psnip_uint32_t uint32_t
87+
# endif
88+
# if !defined(psnip_int16_t)
89+
# define psnip_int16_t int16_t
90+
# endif
91+
# if !defined(psnip_uint16_t)
92+
# define psnip_uint16_t uint16_t
93+
# endif
94+
# if !defined(psnip_int8_t)
95+
# define psnip_int8_t int8_t
96+
# endif
97+
# if !defined(psnip_uint8_t)
98+
# define psnip_uint8_t uint8_t
99+
# endif
100+
# endif
75101
#endif /* !defined(PSNIP_SAFE_NO_FIXED) */
76102
#include <limits.h>
77103
#include <stdlib.h>

tests/atomic.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <stdlib.h>
2+
#include "../exact-int/exact-int.h"
23
#include "../atomic/atomic.h"
34
#include "munit/munit.h"
45

tests/builtin.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#include "munit/munit.h"
55

6+
#include "../exact-int/exact-int.h"
7+
68
#define PSNIP_BUILTIN_EMULATE_NATIVE
79
#include "../builtin/builtin.h"
810

0 commit comments

Comments
 (0)