Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/SaadAhmad/in_constexpr
An approach for runtime detection inside a constexpr function
https://github.com/SaadAhmad/in_constexpr
constexpr constexpr-context constexpr-runtime-detection if-constexpr
Last synced: 3 months ago
JSON representation
An approach for runtime detection inside a constexpr function
- Host: GitHub
- URL: https://github.com/SaadAhmad/in_constexpr
- Owner: SaadAhmad
- License: bsl-1.0
- Created: 2017-08-07T05:28:53.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2018-07-15T06:39:23.000Z (over 6 years ago)
- Last Synced: 2024-08-02T01:25:43.658Z (6 months ago)
- Topics: constexpr, constexpr-context, constexpr-runtime-detection, if-constexpr
- Language: C++
- Homepage:
- Size: 20.5 KB
- Stars: 80
- Watchers: 6
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE_1_0.txt
Awesome Lists containing this project
- AwesomeCppGameDev - in_constexpr
README
# About in_constexpr
An approach of detecting if inside a constexpr context in a constexpr function.By being able to detect if we're within a constexpr context we can choose to implement
a runtime specific algorithm while having a different algorithm for doing something at compile time.The approach is discussed in [this post](http://saadahmad.ca/detecting-evaluation-context-inside-constexpr-functions/)
# Features
* if (in_constexpr()/in_runtime()) - Being able to detect if in runtime or compile time
* smart_assert - constexpr friendly assert# Constraints
* Only tested on GCC 5+ and Clang 3.8+
* x86 only so far
* Runtime approach only works on linux (replacing code in the binary should work under windows for now)
* See detailed descriptions about caveats [here](http://saadahmad.ca/detecting-evaluation-context-inside-constexpr-functions/#caveats)
* The library must be statically linked
* The initialization logic relies on being able to modify the .text segment of your program# Using the library
## Building and installing
You can compile and install this library using cmake. You will need to link this library in as a static library.
You can customize and install the library using the following:
```
cmake-DCMAKE_INSTALL_PREFIX= && make -j && make install
```
Then just link in as you would a normal library. You can try the examples in examples/ to see how to use the library.
## Using the API and an exampleTo test if this library is working, you can call ```in_constexpr::is_setup()``` to see if it is working. The library should automatically call the setup by means of the constructor
attribute and so you shouldn't need to explicitly call ```in_constexpr::initialize()``` but if it's not happening automatically, you can call that function.The library provides an ``` in_constexpr()``` and ```in_runtime()``` macro/method that returns if a constexpr function is within which context. This can be used to provide different code paths in each case.
Note, you can't do something like ```if (!in_constexpr()) ``` due to those methods being a syntatic sugar. Use either ```if (in_constexpr())``` or ```if (in_runtime())```.The library also provides a smart_assert which you can use regular assert but stil work within constexpr functions.
You can find more examples under the examples folder.
```cpp
const int N_MAX = 30;
int factorial_cache[N_MAX] = {0};constexpr int factorial(int n) {
smart_assert(n >= 0 && n < N_MAX, "N >= 0 && N <= N_MAX");if (n == 0)
return 1;
else {
if (in_constexpr()) {
return n * factorial(n - 1);
} else {
std::cout << "Calling factorial " << n << std::endl;
// Since we're in runtime, we can cache results.
if (factorial_cache[n] == 0) {
factorial_cache[n] = n * factorial(n - 1);
}
return factorial_cache[n];
}
}
}int main() {
volatile int a = 5;
volatile int b = 6;
std::cout << factorial(a) << std::endl;
std::cout << factorial(b) << std::endl;constexpr int c = factorial(3);
// Compiler error!
// constexpr int d = factorial(-5);std::cout << c << std::endl;
// std::cout << factorial(d) << std::endl;
return 0;
}
```
Will produce the following outputs
```
Calling factorial 5
Calling factorial 4
Calling factorial 3
Calling factorial 2
Calling factorial 1
120
Calling factorial 6
Calling factorial 5
720
6
```