From bd4cb84e80fee6c0bf428b17a92c0799e1b2d696 Mon Sep 17 00:00:00 2001 From: Arsenic <54987647+Arsenic-ATG@users.noreply.github.com> Date: Sat, 19 Mar 2022 21:40:40 +0530 Subject: [PATCH] C++17: Add __has_include operator (#112) --- CPP17.md | 38 ++++++++++++++++++++++++++++++++++++++ README.md | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/CPP17.md b/CPP17.md index 3d42d6a..9898ac9 100644 --- a/CPP17.md +++ b/CPP17.md @@ -18,6 +18,7 @@ C++17 includes the following new language features: - [utf-8 character literals](#utf-8-character-literals) - [direct-list-initialization of enums](#direct-list-initialization-of-enums) - [fallthrough, nodiscard, maybe_unused attributes](#fallthrough-nodiscard-maybe_unused-attributes) +- [\_\_has\_include](#\_\_has\_include) C++17 includes the following new library features: - [std::variant](#stdvariant) @@ -309,6 +310,43 @@ void my_callback(std::string msg, [[maybe_unused]] bool error) { } ``` +### \_\_has\_include + +`__has_include (operand)` operator may be used in `#if` and `#elif` expressions to check whether a header or source file (`operand`) is available for inclusion or not. + +One use case of this would be using two libraries that work the same way, using the backup/experimental one if the preferred one is not found on the system. + +```c++ +#ifdef __has_include +# if __has_include() +# include +# define have_optional 1 +# elif __has_include() +# include +# define have_optional 1 +# define experimental_optional +# else +# define have_optional 0 +# endif +#endif +``` + +It can also be used to include headers existing under different names or locations on various platforms, without knowing which platform the program is running on, OpenGL headers are a good example for this which are located in `OpenGL\` directory on macOS and `GL\` on other platforms. + +```c++ +#ifdef __has_include +# if __has_include() +# include +# include +# elif __has_include() +# include +# include +# else +# error No suitable OpenGL headers found. +# endif +#endif +``` + ## C++17 Library Features ### std::variant diff --git a/README.md b/README.md index fa93ca6..047be8d 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ C++17 includes the following new language features: - [utf-8 character literals](#utf-8-character-literals) - [direct-list-initialization of enums](#direct-list-initialization-of-enums) - [fallthrough, nodiscard, maybe_unused attributes](#fallthrough-nodiscard-maybe_unused-attributes) +- [\_\_has\_include](#\_\_has\_include) C++17 includes the following new library features: - [std::variant](#stdvariant) @@ -960,6 +961,43 @@ void my_callback(std::string msg, [[maybe_unused]] bool error) { } ``` +### \_\_has\_include + +`__has_include (operand)` operator may be used in `#if` and `#elif` expressions to check whether a header or source file (`operand`) is available for inclusion or not. + +One use case of this would be using two libraries that work the same way, using the backup/experimental one if the preferred one is not found on the system. + +```c++ +#ifdef __has_include +# if __has_include() +# include +# define have_optional 1 +# elif __has_include() +# include +# define have_optional 1 +# define experimental_optional +# else +# define have_optional 0 +# endif +#endif +``` + +It can also be used to include headers existing under different names or locations on various platforms, without knowing which platform the program is running on, OpenGL headers are a good example for this which are located in `OpenGL\` directory on macOS and `GL\` on other platforms. + +```c++ +#ifdef __has_include +# if __has_include() +# include +# include +# elif __has_include() +# include +# include +# else +# error No suitable OpenGL headers found. +# endif +#endif +``` + ## C++17 Library Features ### std::variant