1#pragma once
2
3// https://stackoverflow.com/questions/53365538/how-to-determine-whether-to-use-filesystem-or-experimental-filesystem
4// https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros
5
6// We haven't checked which filesystem to include yet
7#ifndef INCLUDE_STD_FILESYSTEM_EXPERIMENTAL
8
9// Check for feature test macro for <filesystem>
10#if defined(__cpp_lib_filesystem)
11#define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 0
12
13// Check for feature test macro for <experimental/filesystem>
14#elif defined(__cpp_lib_experimental_filesystem)
15#define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 1
16
17// We can't check if headers exist...
18// Let's assume experimental to be safe
19#elif !defined(__has_include)
20#define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 1
21
22// Check if the header "<filesystem>" exists
23#elif __has_include(<filesystem>)
24
25// If we're compiling on Visual Studio and are not compiling with C++17, we need
26// to use experimental
27#ifdef _MSC_VER
28
29// Check and include header that defines "_HAS_CXX17"
30#if __has_include(<yvals_core.h>)
31#include <yvals_core.h>
32
33// Check for enabled C++17 support
34#if defined(_HAS_CXX17) && _HAS_CXX17
35// We're using C++17, so let's use the normal version
36#define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 0
37#endif
38#endif
39
40// If the marco isn't defined yet, that means any of the other VS specific
41// checks failed, so we need to use experimental
42#ifndef INCLUDE_STD_FILESYSTEM_EXPERIMENTAL
43#define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 1
44#endif
45
46// Not on Visual Studio. Let's use the normal version
47#else // #ifdef _MSC_VER
48#define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 0
49#endif
50
51// Check if the header "<filesystem>" exists
52#elif __has_include(<experimental/filesystem>)
53#define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 1
54
55// Fail if neither header is available with a nice error message
56#else
57#error Could not find system header "<filesystem>" or "<experimental/filesystem>"
58#endif
59
60// We priously determined that we need the exprimental version
61#if INCLUDE_STD_FILESYSTEM_EXPERIMENTAL
62// Include it
63#include <experimental/filesystem>
64
65// We need the alias from std::experimental::filesystem to std::filesystem
66namespace std {
67namespace filesystem = experimental::filesystem;
68}
69
70// We have a decent compiler and can use the normal version
71#else
72// Include it
73#include <filesystem>
74#endif
75
76#endif // #ifndef INCLUDE_STD_FILESYSTEM_EXPERIMENTAL
77