From this Stack Overflow answer, I learned that C++17 will have __has_include
, which can
[make] migrating from experimental to std almost seamless
This still leaves the question of how to do it. Doing something like namespace std { using namespace std::experimental; }
is undefined behaviour, so I came up with this method:
optional.h demonstration on coliru
#pragma once
#if __has_include(<optional>)
# include <optional>
# define HAS_STD_OPTIONAL
#elif __has_include(<experimental/optional>)
# include <experimental/optional>
# define HAS_STD_EXPERIMENTAL_OPTIONAL
#else
# error Must have an optional type, either from <optional> or if not supported from <experimental/optional>.
#endif
#if defined HAS_STD_OPTIONAL
namespace opt {
template<class T>
using optional = std::optional<T>;
using bad_optional_access = std::bad_optional_access;
using nullopt_t = std::nullopt_t;
using in_place_t = std::in_place_t;
constexpr auto nullopt = std::nullopt;
constexpr auto in_place = std::in_place;
template<class T>
constexpr auto make_optional(T && value)
{
return std::make_optional(std::forward<T>(value));
}
}
#elif defined HAS_STD_EXPERIMENTAL_OPTIONAL
namespace opt {
template<class T>
using optional = std::experimental::optional<T>;
using bad_optional_access = std::experimental::bad_optional_access;
using nullopt_t = std::experimental::nullopt_t;
using in_place_t = std::experimental::in_place_t;
constexpr auto nullopt = std::experimental::nullopt;
constexpr auto in_place = std::experimental::in_place;
template<class T>
constexpr auto make_optional(T && value)
{
return std::experimental::make_optional(std::forward<T>(value));
}
}
#endif