{"id":13645918,"url":"https://github.com/SaadAhmad/in_constexpr","last_synced_at":"2025-04-21T17:31:35.429Z","repository":{"id":70446320,"uuid":"99539846","full_name":"SaadAhmad/in_constexpr","owner":"SaadAhmad","description":"An approach for runtime detection inside a constexpr function","archived":false,"fork":false,"pushed_at":"2018-07-15T06:39:23.000Z","size":21,"stargazers_count":80,"open_issues_count":0,"forks_count":1,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-11-09T19:39:46.807Z","etag":null,"topics":["constexpr","constexpr-context","constexpr-runtime-detection","if-constexpr"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SaadAhmad.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE_1_0.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-08-07T05:28:53.000Z","updated_at":"2024-01-04T16:16:16.000Z","dependencies_parsed_at":null,"dependency_job_id":"c9341dac-9388-4338-8e60-fa99a5a9511d","html_url":"https://github.com/SaadAhmad/in_constexpr","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SaadAhmad%2Fin_constexpr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SaadAhmad%2Fin_constexpr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SaadAhmad%2Fin_constexpr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SaadAhmad%2Fin_constexpr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SaadAhmad","download_url":"https://codeload.github.com/SaadAhmad/in_constexpr/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250100470,"owners_count":21374948,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["constexpr","constexpr-context","constexpr-runtime-detection","if-constexpr"],"created_at":"2024-08-02T01:02:44.975Z","updated_at":"2025-04-21T17:31:35.189Z","avatar_url":"https://github.com/SaadAhmad.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"# About in_constexpr\nAn approach of detecting if inside a constexpr context in a constexpr function. \n\nBy being able to detect if we're within a constexpr context we can choose to implement\na runtime specific algorithm while having a different algorithm for doing something at compile time. \n\nThe approach is discussed in [this post](http://saadahmad.ca/detecting-evaluation-context-inside-constexpr-functions/)\n\n# Features\n* if (in_constexpr()/in_runtime()) - Being able to detect if in runtime or compile time \n* smart_assert                     - constexpr friendly assert\n\n# Constraints\n* Only tested on GCC 5+ and Clang 3.8+\n* x86 only so far\n* Runtime approach only works on linux (replacing code in the binary should work under windows for now)\n* See detailed descriptions about caveats [here](http://saadahmad.ca/detecting-evaluation-context-inside-constexpr-functions/#caveats)\n* The library must be statically linked\n* The initialization logic relies on being able to modify the .text segment of your program\n\n# Using the library\n## Building and installing\nYou can compile and install this library using cmake. You will need to link this library in as a static library.\nYou can customize and install the library using the following:\n```\ncmake \u003ccode directory\u003e -DCMAKE_INSTALL_PREFIX=\u003cinstall directory\u003e \u0026\u0026 make -j \u0026\u0026 make install\n```\nThen just link in as you would a normal library. You can try the examples in examples/ to see how to use the library.\n## Using the API and an example\n\nTo 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 \nattribute and so you shouldn't need to explicitly call ```in_constexpr::initialize()``` but if it's not happening automatically, you can call that function. \n\nThe 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. \nNote, 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())```.\n\nThe library also provides a smart_assert which you can use regular assert but stil work within constexpr functions. \n\nYou can find more examples under the examples folder. \n\n```cpp\n\nconst int N_MAX            = 30;\nint factorial_cache[N_MAX] = {0};\n\nconstexpr int factorial(int n) {\n  smart_assert(n \u003e= 0 \u0026\u0026 n \u003c N_MAX, \"N \u003e= 0 \u0026\u0026 N \u003c= N_MAX\");\n\n  if (n == 0)\n    return 1;\n  else {\n    if (in_constexpr()) {\n      return n * factorial(n - 1);\n    } else {\n      std::cout \u003c\u003c \"Calling factorial \" \u003c\u003c n \u003c\u003c std::endl;\n      // Since we're in runtime, we can cache results.\n      if (factorial_cache[n] == 0) {\n        factorial_cache[n] = n * factorial(n - 1);\n      }\n      return factorial_cache[n];\n    }\n  }\n}\n\nint main() {\n  volatile int a = 5;\n  volatile int b = 6;\n  std::cout \u003c\u003c factorial(a) \u003c\u003c std::endl;\n  std::cout \u003c\u003c factorial(b) \u003c\u003c std::endl;\n\n  constexpr int c = factorial(3);\n  // Compiler error!\n  // constexpr int d = factorial(-5);\n\n  std::cout \u003c\u003c c \u003c\u003c std::endl;\n  // std::cout \u003c\u003c factorial(d) \u003c\u003c std::endl;\n  return 0;\n}\n```\nWill produce the following outputs\n```\nCalling factorial 5\nCalling factorial 4\nCalling factorial 3\nCalling factorial 2\nCalling factorial 1\n120\nCalling factorial 6\nCalling factorial 5\n720\n6\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSaadAhmad%2Fin_constexpr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FSaadAhmad%2Fin_constexpr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSaadAhmad%2Fin_constexpr/lists"}