Skip to content

Commit

Permalink
Update compatibility with std:: (#42)
Browse files Browse the repository at this point in the history
* Use std::nullopt if possible

* Use std::pointer_traits::to_address if possible

* Update README.md

* Fix dumb MSVC bug
  • Loading branch information
lackhole committed Aug 26, 2024
1 parent c3e3fb0 commit 1738a35
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 64 deletions.
119 changes: 64 additions & 55 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -770,52 +770,57 @@ Description

#### `<memory>`

| | Introduced | Revision |
|---------------------------------------------------|------------|------------|
| `pointer_traits` | ![][c11] | ![][c20ok] |
| `aligned_alloc` | ![][c17no] | |
| `destroy_at` | ![][c17ok] | ![][c20ok] |
| `destroy` | ![][c17ok] | ![][c20ok] |
| `destroy_n` | ![][c17ok] | ![][c20ok] |
| `xxx_pointer_cast` | ![][c17ok] | ![][c20ok] |
| `uninitialized_default_construct` | ![][c17no] | ![][c20no] |
| `uninitialized_default_construct_n` | ![][c17no] | ![][c20no] |
| `uninitialized_move` | ![][c17no] | ![][c20no] |
| `uninitialized_move_n` | ![][c17no] | ![][c20no] |
| `uninitialized_value_construct` | ![][c17no] | |
| `uninitialized_value_construct_n` | ![][c17no] | |
| `atomic<shared_ptr>` | ![][c20no] | |
| `atomic<unique_ptr>` | ![][c20no] | |
| `assume_aligned` | ![][c20no] | |
| `construct_at` | ![][c20ok] | |
| `make_shared_for_overwrite` | ![][c20no] | |
| `make_unique_for_overwrite` | ![][c20no] | |
| `allocate_shared_for_overwrite` | ![][c20no] | |
| `to_address` | ![][c20ok] | |
| `uses_allocator_construction_args` | ![][c20ok] | |
| `make_obj_using_allocator` | ![][c20ok] | |
| `uninitialized_construct_using_allocator` | ![][c20no] | |
| `operator<<(std::unique_ptr)` | ![][c20no] | |
| `ranges::construct_at` | ![][c20no] | |
| `ranges::destroy` | ![][c20no] | |
| `ranges::destroy_n` | ![][c20no] | |
| `ranges::destroy_at` | ![][c20no] | |
| `ranges::uninitialized_copy` | ![][c20no] | |
| `ranges::uninitialized_copy_n` | ![][c20no] | |
| `ranges::uninitialized_fill` | ![][c20no] | |
| `ranges::uninitialized_fill_n` | ![][c20no] | |
| `ranges::uninitialized_move` | ![][c20no] | |
| `ranges::uninitialized_move_n` | ![][c20no] | |
| `ranges::uninitialized_default_construct` | ![][c20no] | |
| `ranges::uninitialized_default_construct_n` | ![][c20no] | |
| `ranges::uninitialized_value_construct` | ![][c20no] | |
| `ranges::uninitialized_value_construct_n` | ![][c20no] | |
| `allocation_result` | ![][c23no] | |
| `inout_ptr`<br/>`inout_ptr_t` | ![][c23no] | |
| `out_ptr`<br/>`out_ptr_t` | ![][c23no] | |
| `start_lifetime_as`<br/>`start_lifetime_as_array` | ![][c23no] | |
| `owner_hash` | ![][c26no] | |
| `owner_equal` | ![][c26no] | |
| | Introduced | Revision |
|---------------------------------------------------|-------------|------------|
| `pointer_traits` | ![][c11] | ![][c20ok] |
| `aligned_alloc` | ![][c17no] | |
| `destroy_at` | ![][c17ok] | ![][c20ok] |
| `destroy` | ![][c17ok] | ![][c20ok] |
| `destroy_n` | ![][c17ok] | ![][c20ok] |
| `xxx_pointer_cast` | ![][c17ok] | ![][c20ok] |
| `uninitialized_default_construct` | ![][c17no] | ![][c20no] |
| `uninitialized_default_construct_n` | ![][c17no] | ![][c20no] |
| `uninitialized_move` | ![][c17no] | ![][c20no] |
| `uninitialized_move_n` | ![][c17no] | ![][c20no] |
| `uninitialized_value_construct` | ![][c17no] | |
| `uninitialized_value_construct_n` | ![][c17no] | |
| `atomic<shared_ptr>` | ![][c20no] | |
| `atomic<unique_ptr>` | ![][c20no] | |
| `assume_aligned` | ![][c20no] | |
| `construct_at` | ![][c20ok] | |
| `make_shared_for_overwrite` | ![][c20no] | |
| `make_unique_for_overwrite` | ![][c20no] | |
| `allocate_shared_for_overwrite` | ![][c20no] | |
| `to_address` | ![][c20ok]* | |
| `uses_allocator_construction_args` | ![][c20ok] | |
| `make_obj_using_allocator` | ![][c20ok] | |
| `uninitialized_construct_using_allocator` | ![][c20no] | |
| `operator<<(std::unique_ptr)` | ![][c20no] | |
| `ranges::construct_at` | ![][c20no] | |
| `ranges::destroy` | ![][c20no] | |
| `ranges::destroy_n` | ![][c20no] | |
| `ranges::destroy_at` | ![][c20no] | |
| `ranges::uninitialized_copy` | ![][c20no] | |
| `ranges::uninitialized_copy_n` | ![][c20no] | |
| `ranges::uninitialized_fill` | ![][c20no] | |
| `ranges::uninitialized_fill_n` | ![][c20no] | |
| `ranges::uninitialized_move` | ![][c20no] | |
| `ranges::uninitialized_move_n` | ![][c20no] | |
| `ranges::uninitialized_default_construct` | ![][c20no] | |
| `ranges::uninitialized_default_construct_n` | ![][c20no] | |
| `ranges::uninitialized_value_construct` | ![][c20no] | |
| `ranges::uninitialized_value_construct_n` | ![][c20no] | |
| `allocation_result` | ![][c23no] | |
| `inout_ptr`<br/>`inout_ptr_t` | ![][c23no] | |
| `out_ptr`<br/>`out_ptr_t` | ![][c23no] | |
| `start_lifetime_as`<br/>`start_lifetime_as_array` | ![][c23no] | |
| `owner_hash` | ![][c26no] | |
| `owner_equal` | ![][c26no] | |

* Notes
* `to_address`
* If `std::pointer_traits::to_address` is available, it is used before `preview::pointer_traits::to_address`.
* ⚠️ `std::pointer_traits::to_address` is not sfinae-friendly until MSVC 2022, so not used.

#### `<memory_resource>`
N/A
Expand Down Expand Up @@ -888,15 +893,19 @@ Description

#### `<optional>`

| | Introduced | Revision |
|-----------------------|------------|-----------------------|
| `optional` | ![][c17ok] | ![][c23ok] ![][c26no] |
| `bad_optional_access` | ![][c17ok] | |
| `std::hash<optional>` | ![][c17ok] | |
| `nullopt` | ![][c17ok] | |
| `nullopt_t` | ![][c17ok] | |
| `swap(optional)` | ![][c17ok] | |
| `make_optional` | ![][c17ok] | |
| | Introduced | Revision |
|-----------------------|-------------|-----------------------|
| `optional` | ![][c17ok] | ![][c23ok] ![][c26no] |
| `bad_optional_access` | ![][c17ok] | |
| `std::hash<optional>` | ![][c17ok] | |
| `nullopt` | ![][c17ok]* | |
| `nullopt_t` | ![][c17ok]* | |
| `swap(optional)` | ![][c17ok] | |
| `make_optional` | ![][c17ok] | |

* Notes
* `nullopt`, `nullopt_t`
* `std::nullopt` is used if available, `preview::nullopt` otherwise.

#### `<random>`

Expand Down
29 changes: 22 additions & 7 deletions include/preview/__memory/to_address.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,39 @@
#include <type_traits>

#include "preview/__memory/pointer_traits.h"
#include "preview/__type_traits/detail/tag.h"
#include "preview/__type_traits/has_operator_arrow.h"
#include "preview/__type_traits/void_t.h"

namespace preview {
namespace detail {

template<typename T, typename = void>
template<typename T, template<typename> class Traits, typename = void>
struct has_to_address : std::false_type {};

template<typename T, template<typename> class Traits>
struct has_to_address<T, Traits, void_t<decltype(Traits<T>::to_address(std::declval<const T&>()))>> : std::true_type {};

template<typename T>
struct has_to_address<T, void_t<decltype(pointer_traits<T>::to_address(std::declval<const T&>()))>> : std::true_type {};
using to_address_tag = conditional_tag<
#if defined(_MSC_VER) && _MSC_VER < 1930 // std::pointer_traits is not sfinae-friendly before VS 2022
has_to_address<T, pointer_traits>
#else
has_to_address<T, std::pointer_traits>,
has_to_address<T, pointer_traits>
#endif
>;

template<typename T>
constexpr auto to_address_fancy(const T& p, std::true_type /* has_to_address */ ) noexcept {
return preview::pointer_traits<T>::to_address(p);
constexpr auto to_address_fancy(const T& p, preview::detail::tag_1 /* std::pointer_traits<T>::to_address */ ) noexcept {
return std::pointer_traits<T>::to_address(p);
}
template<typename T>
constexpr auto to_address_fancy(const T& p, preview::detail::tag_2 /* pointer_traits<T>::to_address */ ) noexcept {
return pointer_traits<T>::to_address(p);
}
template<typename T>
constexpr auto to_address_fancy(const T& p, std::false_type /* has_to_address */ ) noexcept;
constexpr auto to_address_fancy(const T& p, preview::detail::tag_else /* no to_address */ ) noexcept;

} // namespace detail

Expand All @@ -38,13 +53,13 @@ constexpr T* to_address(T* p) noexcept {

template<class T>
constexpr auto to_address(const T& p) noexcept {
return detail::to_address_fancy(p, detail::has_to_address<T>{});
return detail::to_address_fancy(p, detail::to_address_tag<T>{});
}

namespace detail {

template<typename T>
constexpr auto to_address_fancy(const T& p, std::false_type /* has_to_address */ ) noexcept {
constexpr auto to_address_fancy(const T& p, preview::detail::tag_else /* no to_address */ ) noexcept {
return preview::to_address(p.operator->());
}

Expand Down
21 changes: 19 additions & 2 deletions include/preview/__optional/nullopt_t.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,30 @@
# ifndef PREVIEW_OPTIONAL_NULLOPT_T_H_
# define PREVIEW_OPTIONAL_NULLOPT_T_H_

#include "preview/__core/std_version.h"

#if PREVIEW_CXX_VERSION >= 17
#include <optional>
#endif

namespace preview {

#if PREVIEW_CXX_VERSION >= 17

using nullopt_t = std::nullopt_t;
constexpr nullopt_t nullopt{std::nullopt};

#else

struct nullopt_t {
constexpr explicit nullopt_t(int) {}
struct ctor_tag {};
constexpr explicit nullopt_t(ctor_tag, ctor_tag) {}
};

constexpr nullopt_t nullopt{0};
constexpr nullopt_t nullopt{nullopt_t::ctor_tag{}, nullopt_t::ctor_tag{}};

#endif


} // namespace preview

Expand Down

0 comments on commit 1738a35

Please sign in to comment.