Skip to content

Commit e0f1072

Browse files
committed
Merge C++20 bit operations support and modernization by Aki Kuri Chan
1 parent 0d918d9 commit e0f1072

7 files changed

Lines changed: 269 additions & 1 deletion

File tree

docs/CODE_OF_CONDUCT.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Contributor Covenant Code of Conduct
2+
3+
## Our Pledge
4+
5+
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual orientation.
6+
7+
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
8+
9+
## Our Standards
10+
11+
Examples of behavior that contributes to a positive environment for our community include:
12+
13+
* Demonstrating empathy and kindness toward other people
14+
* Being respectful of differing opinions, viewpoints, and experiences
15+
* Giving and gracefully accepting constructive feedback
16+
* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
17+
* Focusing on what is best not just for us as individuals, but for the overall community
18+
19+
Examples of unacceptable behavior include:
20+
21+
* The use of sexualized language or imagery, and sexual attention or advances of any kind
22+
* Trolling, insulting or derogatory comments, and personal or political attacks
23+
* Public or private harassment
24+
* Publishing others' private information, such as a physical or email address, without their explicit permission
25+
* Other conduct which could reasonably be considered inappropriate in a professional setting
26+
27+
## Enforcement Responsibilities
28+
29+
Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
30+
31+
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
32+
33+
## Scope
34+
35+
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
36+
37+
## Enforcement
38+
39+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [INSERT CONTACT METHOD, e.g., email or create a private issue].
40+
All complaints will be reviewed and investigated promptly and fairly.
41+
42+
All community leaders are obligated to respect the privacy and security of the reporter of any incident.

docs/CONTRIBUTING.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Contributing
2+
3+
The license for this work does not require you to share changes you make
4+
in your own version of the code. Contributions are welcome, however.
5+
6+
## License
7+
8+
This work is licensed under either of
9+
10+
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE.txt) or http://www.apache.org/licenses/LICENSE-2.0)
11+
* MIT license ([LICENSE-MIT](LICENSE-MIT.txt) or http://opensource.org/licenses/MIT)
12+
13+
at your option.
14+
15+
## Contribution Policy
16+
17+
Unless you explicitly state otherwise, any contribution intentionally
18+
submitted for inclusion in this work by you, as defined in the
19+
Apache-2.0 license, shall be dual licensed as above, without any
20+
additional terms or conditions.

docs/CREDITS.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Credits and Attributions
2+
3+
This modernized fork of `pcg-cpp` by **Total-Random** integrates several critical fixes and improvements from the community. Below is a list of changes and their original sources.
4+
5+
---
6+
7+
## Community Fixes
8+
9+
### 1. Optimized `unxorshift`
10+
11+
- **Origin:** [imneme/pcg-cpp PR #82](https://github.com/imneme/pcg-cpp/pull/82)
12+
- **Author:** [LRFLEW](https://github.com/LRFLEW)
13+
- **Description:** Implements a more efficient inverse xorshift operation.
14+
15+
### 2. Empty Base Class Optimization (EBCO) for MSVC
16+
17+
- **Origin:** [imneme/pcg-cpp PR #66](https://github.com/imneme/pcg-cpp/pull/66)
18+
- **Author:** [melak47](https://github.com/melak47)
19+
- **Description:** Enables `__declspec(empty_bases)` on MSVC to optimize the memory footprint of RNG objects.
20+
21+
### 3. Public `result_type` in `seed_seq_from`
22+
23+
- **Origin:** [imneme/pcg-cpp PR #83](https://github.com/imneme/pcg-cpp/pull/83)
24+
- **Author:** [timo-eichhorn](https://github.com/timo-eichhorn)
25+
- **Description:** Makes `result_type` public to comply with the C++ `SeedSequence` concept.
26+
27+
### 4. GCC Warning Fixes
28+
29+
- **Origin:** [SupercriticalSynthesizers/pcg-cpp PR fix-gcc-warnings](https://github.com/SupercriticalSynthesizers/pcg-cpp/tree/fix-gcc-warnings)
30+
- **Author:** [Timo Alho](https://github.com/tialho)
31+
- **Description:** Resolves various GCC warnings (clz/ctz truncation) when building with `-Wall`.
32+
33+
### 5. Native Windows ARM64 Support
34+
35+
- **Origin:** [imneme/pcg-cpp PR #99](https://github.com/imneme/pcg-cpp/pull/99)
36+
- **Author:** [Demonese](https://github.com/Demonese)
37+
- **Description:** Added native support for ARM64 on MSVC using `__umulh` for efficient 128-bit multiplication.
38+
39+
### 6. Sample and Include Cleanups
40+
41+
- **Author:** [brt-v](https://github.com/brt-v)
42+
- **Description:** Simplified header includes in sample programs and added `basic_usage.cpp` sample.
43+
44+
---
45+
46+
## Total-Random Improvements
47+
48+
### 7. Modern CMake Build System
49+
50+
- **Author:** [JkarVN](https://github.com/JkarVN)
51+
- **Description:** Comprehensive CMake integration with automated testing via `ctest`.
52+
53+
### 8. MSVC Compatibility Fixes
54+
55+
- **Author:** [JkarVN](https://github.com/JkarVN)
56+
- **Description:** Resolved several MSVC-specific issues (C2678, C4458, C1090, C4127).
57+
58+
### 9. Modern C++ Best Practices
59+
60+
- **Author:** [Antigravity AI](https://github.com/google-deepmind)
61+
- **Description:**
62+
- Implementation of `PCG_NODISCARD` and modernize using `using` syntax.
63+
64+
### 10. C++20 Bit Infrastructure Integration
65+
66+
- **Author:** **Aki Kuri** ([@akikurichan](https://github.com/akikurichan))
67+
- **Description:**
68+
- Integration of C++20 `<bit>` header support for `rotl`, `rotr`, `flog2`, and `trailingzeros`.
69+
- Introduction of the `PCG_USE_BIT_HEADER` macro toggle for explicit bit operation control.
70+
- Merged from pcg-next
71+
72+
---
73+
74+
## Special Thanks
75+
76+
- **Melissa O'Neill** for the original PCG library.
77+
- **Ben Haller** ([bhaller](https://github.com/bhaller)) for early support.
78+
- **Robert Roessler** ([robertroessler](https://github.com/robertroessler)) for suggesting C++20 bit functions, implemented by **Aki Kuri**.

docs/GOVERNANCE.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Project Governance
2+
3+
The **pcg-cpp** project (under the **Total-Random** organization) is a community-driven open-source project. Our goal is to maintain and modernize the PCG random number generator library for C++, ensuring it remains accessible, stable, and performant for everyone.
4+
5+
We believe that the best way to ensure the longevity of this project is to empower the community to take ownership.
6+
7+
## 1. Principles
8+
9+
* **Openness:** All decision-making happens in public (GitHub Issues/Discussions).
10+
* **Meritocracy:** Influence is earned through active contribution and commitment to the project.
11+
* **Consensus:** We strive for consensus in all technical and governance decisions.
12+
13+
## 2. Roles
14+
15+
### Contributors
16+
Anyone who contributes to the project is a Contributor. Contributions include:
17+
* Submitting Pull Requests (code, documentation, tests).
18+
* Reporting issues and reproduction steps.
19+
* Helping others in discussions.
20+
21+
### Maintainers
22+
Maintainers are Contributors who have demonstrated a long-term commitment to the project's success. They have write access to the repository.
23+
24+
**Responsibilities:**
25+
* Reviewing and merging Pull Requests.
26+
* Triaging and managing Issues.
27+
* Ensuring code quality, CI stability, and release management.
28+
* Mentoring new contributors.
29+
30+
### Admins (Total-Random)
31+
Currently, the **Total-Random** organization holds administrative access. However, our intent is to facilitate the technical leadership of the Maintainers. Admins will intervene only in critical situations (e.g., security, code of conduct violations).
32+
33+
## 3. Decision Making
34+
35+
Process for making changes:
36+
1. **Discussion:** Open an Issue or Pull Request to propose a change.
37+
2. **Review:** At least one Maintainer must review and approve the change.
38+
3. **Consensus:** For major changes (API breaking, governance), we seek lazy consensus (wait 72 hours for objections).
39+
40+
## 4. Becoming a Maintainer
41+
42+
We actively welcome new Maintainers. To become a Maintainer:
43+
1. Demonstrate consistent contributions (PRs, reviews, helpful comments).
44+
2. Express interest in helping maintain the project.
45+
3. Existing Maintainers will vote/agree.
46+
47+
## 5. Code of Conduct
48+
49+
All participants must adhere to our [Code of Conduct](CODE_OF_CONDUCT.md) to ensure a safe and welcoming environment.

include/pcg_extras.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@
4444
#include <utility>
4545
#include <locale>
4646
#include <iterator>
47+
#include <limits>
48+
49+
#if __cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) || defined(PCG_USE_BIT_HEADER)
50+
#include <bit>
51+
#define PCG_BIT_SUPPORT 1
52+
#endif
4753

4854
#ifdef __GNUC__
4955
#include <cxxabi.h>
@@ -287,6 +293,11 @@ inline itype unxorshift(itype x, bitcount_t bits, bitcount_t shift)
287293
template <typename itype>
288294
inline itype rotl(itype value, bitcount_t rot)
289295
{
296+
#if PCG_BIT_SUPPORT
297+
if constexpr (std::is_integral_v<itype> && std::is_unsigned_v<itype>) {
298+
return std::rotl(value, (int)rot);
299+
}
300+
#endif
290301
constexpr bitcount_t bits = sizeof(itype) * 8;
291302
constexpr bitcount_t mask = bits - 1;
292303
#if PCG_USE_ZEROCHECK_ROTATE_IDIOM
@@ -299,6 +310,11 @@ inline itype rotl(itype value, bitcount_t rot)
299310
template <typename itype>
300311
inline itype rotr(itype value, bitcount_t rot)
301312
{
313+
#if PCG_BIT_SUPPORT
314+
if constexpr (std::is_integral_v<itype> && std::is_unsigned_v<itype>) {
315+
return std::rotr(value, (int)rot);
316+
}
317+
#endif
302318
constexpr bitcount_t bits = sizeof(itype) * 8;
303319
constexpr bitcount_t mask = bits - 1;
304320
#if PCG_USE_ZEROCHECK_ROTATE_IDIOM

include/pcg_uint128.hpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@
4040
#include <cstdio>
4141
#include <cassert>
4242
#include <climits>
43+
44+
#if __cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) || defined(PCG_USE_BIT_HEADER)
45+
#include <bit>
46+
#ifndef PCG_BIT_SUPPORT
47+
#define PCG_BIT_SUPPORT 1
48+
#endif
49+
#endif
50+
#include <cassert>
4351
#include <utility>
4452
#include <initializer_list>
4553
#include <type_traits>
@@ -100,7 +108,29 @@ namespace pcg_extras {
100108
* * trailingzeros number of trailing zero bits
101109
*/
102110

103-
#if defined(__GNUC__) // Any GNU-compatible compiler supporting C++11 has
111+
#if PCG_BIT_SUPPORT
112+
113+
inline bitcount_t flog2(uint32_t v)
114+
{
115+
return bitcount_t(std::bit_width(v) - 1);
116+
}
117+
118+
inline bitcount_t trailingzeros(uint32_t v)
119+
{
120+
return bitcount_t(std::countr_zero(v));
121+
}
122+
123+
inline bitcount_t flog2(uint64_t v)
124+
{
125+
return bitcount_t(std::bit_width(v) - 1);
126+
}
127+
128+
inline bitcount_t trailingzeros(uint64_t v)
129+
{
130+
return bitcount_t(std::countr_zero(v));
131+
}
132+
133+
#elif defined(__GNUC__) // Any GNU-compatible compiler supporting C++11 has
104134
// some useful intrinsics we can use.
105135
// These bitcount_t casts are from SupercriticalSynthesizers/pcg-cpp PR fix-gcc-warnings
106136

test_seed_1234.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <cstdint>
4+
#include "include/pcg_random.hpp"
5+
6+
using namespace std;
7+
8+
int main() {
9+
// Both C library and this C++ library default stream might differ if not specified.
10+
// Let's test with just seed = 1234u, and if needed, specific seq.
11+
pcg32 rng(1234u, 54u); // Try with standard sequence 54 provided in samples
12+
pcg32 rng_default(1234u); // Default sequence
13+
14+
vector<uint32_t> expected = {
15+
2653504168,
16+
209608674,
17+
1195720523,
18+
3249742110,
19+
76957682,
20+
3144134622,
21+
2510553852,
22+
2126586030,
23+
2110775405,
24+
2940631255
25+
};
26+
27+
cout << "Testing with pcg32(1234u):" << endl;
28+
for (int i = 0; i < 10; ++i) {
29+
cout << rng_default() << endl;
30+
}
31+
32+
return 0;
33+
}

0 commit comments

Comments
 (0)