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