Skip to content

Commit

Permalink
Merge pull request #283 from ned14/wip-fix-addressof
Browse files Browse the repository at this point in the history
Use a preprocessor macro to control the use of std::addressof(), fixing #282.
  • Loading branch information
ned14 authored Jul 15, 2023
2 parents 7fe6e84 + cc6088d commit 0bedf67
Show file tree
Hide file tree
Showing 12 changed files with 175 additions and 126 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test" AND NOT PROJECT_IS_DEPENDENCY)
add_executable(${target_name} "${testsource}")
if(NOT first_test_target_noexcept)
set(first_test_target_noexcept ${target_name})
elseif(${target_name} MATCHES "coroutine-support|fileopen|hooks")
elseif(${target_name} MATCHES "coroutine-support|fileopen|hooks|core-result")
set_target_properties(${target_name} PROPERTIES DISABLE_PRECOMPILE_HEADERS On)
elseif(COMMAND target_precompile_headers)
target_precompile_headers(${target_name} REUSE_FROM ${first_test_target_noexcept})
Expand Down Expand Up @@ -249,7 +249,7 @@ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test" AND NOT PROJECT_IS_DEPENDENCY)
add_executable(${target_name} "${testsource}")
if(NOT first_test_target_permissive)
set(first_test_target_permissive ${target_name})
elseif(${target_name} MATCHES "coroutine-support|fileopen")
elseif(${target_name} MATCHES "coroutine-support|fileopen|core-result")
set_target_properties(${target_name} PROPERTIES DISABLE_PRECOMPILE_HEADERS On)
elseif(COMMAND target_precompile_headers)
target_precompile_headers(${target_name} REUSE_FROM ${first_test_target_permissive})
Expand Down
5 changes: 3 additions & 2 deletions doc/src/content/changelog/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ This as usual will cause minor breakage due to LEWG renaming of things.

- Outcome previously took addresses of things not using `std::addressof()`, and until now
nobody complained because custom `operator&` which doesn't return an address is an
abomination not used in much modern C++. But finally someone did complain, so it is fixed
for both normal Outcome and Experimental.Outcome.
abomination not used in much modern C++. But finally someone did complain, so
for both normal Outcome and Experimental.Outcome, if you set `OUTCOME_USE_STD_ADDRESSOF = 1`,
Outcome will use `std::addressof()`

### Bug fixes:

Expand Down
7 changes: 7 additions & 0 deletions include/outcome/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,13 @@ template <class T> constexpr in_place_type_t<T> in_place_type{};
OUTCOME_V2_NAMESPACE_END
#endif

#if OUTCOME_USE_STD_ADDRESSOF
#include <memory> // for std::addressof
#define OUTCOME_ADDRESS_OF(...) std::addressof(__VA_ARGS__)
#else
#define OUTCOME_ADDRESS_OF(...) (&__VA_ARGS__)
#endif

#ifndef OUTCOME_TRIVIAL_ABI
#if defined(STANDARDESE_IS_IN_THE_HOUSE) || __clang_major__ >= 7
//! Defined to be `[[clang::trivial_abi]]` when on a new enough clang compiler. Usually automatic, can be overriden.
Expand Down
6 changes: 3 additions & 3 deletions include/outcome/detail/revision.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ Distributed under the Boost Software License, Version 1.0.
*/

// Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time
#define OUTCOME_PREVIOUS_COMMIT_REF 44da28c59d85f2245230931b6c25725b679b556c
#define OUTCOME_PREVIOUS_COMMIT_DATE "2023-06-28 21:21:35 +00:00"
#define OUTCOME_PREVIOUS_COMMIT_UNIQUE 44da28c5
#define OUTCOME_PREVIOUS_COMMIT_REF 06da8aa6452ede5600af3c4ed4781ebd631149f9
#define OUTCOME_PREVIOUS_COMMIT_DATE "2023-07-15 10:37:16 +00:00"
#define OUTCOME_PREVIOUS_COMMIT_UNIQUE 06da8aa6
50 changes: 25 additions & 25 deletions include/outcome/detail/value_storage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1055,11 +1055,11 @@ namespace detail
{
if(o._status.have_value())
{
new(std::addressof(_value)) _value_type_(static_cast<_value_type_ &&>(o._value)); // NOLINT
new(OUTCOME_ADDRESS_OF(_value)) _value_type_(static_cast<_value_type_ &&>(o._value)); // NOLINT
}
else if(o._status.have_error())
{
new(std::addressof(_error)) _error_type_(static_cast<_error_type_ &&>(o._error)); // NOLINT
new(OUTCOME_ADDRESS_OF(_error)) _error_type_(static_cast<_error_type_ &&>(o._error)); // NOLINT
}
_status = o._status;
o._status.set_have_moved_from(true);
Expand All @@ -1072,11 +1072,11 @@ namespace detail
{
if(o._status.have_value())
{
new(std::addressof(_value)) _value_type_(o._value); // NOLINT
new(OUTCOME_ADDRESS_OF(_value)) _value_type_(o._value); // NOLINT
}
else if(o._status.have_error())
{
new(std::addressof(_error)) _error_type_(o._error); // NOLINT
new(OUTCOME_ADDRESS_OF(_error)) _error_type_(o._error); // NOLINT
}
_status = o._status;
}
Expand Down Expand Up @@ -1182,11 +1182,11 @@ namespace detail
{
if(o._status.have_value())
{
new(std::addressof(_value)) _value_type_(); // NOLINT
new(OUTCOME_ADDRESS_OF(_value)) _value_type_(); // NOLINT
}
else if(o._status.have_error())
{
new(std::addressof(_error)) _error_type_(o._error); // NOLINT
new(OUTCOME_ADDRESS_OF(_error)) _error_type_(o._error); // NOLINT
}
_status = o._status;
}
Expand All @@ -1197,11 +1197,11 @@ namespace detail
{
if(o._status.have_value())
{
new(std::addressof(_value)) _value_type_(); // NOLINT
new(OUTCOME_ADDRESS_OF(_value)) _value_type_(); // NOLINT
}
else if(o._status.have_error())
{
new(std::addressof(_error)) _error_type_(static_cast<_error_type_ &&>(o._error)); // NOLINT
new(OUTCOME_ADDRESS_OF(_error)) _error_type_(static_cast<_error_type_ &&>(o._error)); // NOLINT
}
_status = o._status;
o._status.set_have_moved_from(true);
Expand All @@ -1219,11 +1219,11 @@ namespace detail
{
if(o._status.have_value())
{
new(std::addressof(_value)) _value_type_(o._value); // NOLINT
new(OUTCOME_ADDRESS_OF(_value)) _value_type_(o._value); // NOLINT
}
else if(o._status.have_error())
{
new(std::addressof(_error)) _error_type_(); // NOLINT
new(OUTCOME_ADDRESS_OF(_error)) _error_type_(); // NOLINT
}
_status = o._status;
}
Expand All @@ -1234,11 +1234,11 @@ namespace detail
{
if(o._status.have_value())
{
new(std::addressof(_value)) _value_type_(static_cast<_value_type_ &&>(o._value)); // NOLINT
new(OUTCOME_ADDRESS_OF(_value)) _value_type_(static_cast<_value_type_ &&>(o._value)); // NOLINT
}
else if(o._status.have_error())
{
new(std::addressof(_error)) _error_type_(); // NOLINT
new(OUTCOME_ADDRESS_OF(_error)) _error_type_(); // NOLINT
}
_status = o._status;
o._status.set_have_moved_from(true);
Expand Down Expand Up @@ -1325,7 +1325,7 @@ namespace detail
if(_status.have_value() && !o._status.have_error())
{
// Move construct me into other
new(std::addressof(o._value)) _value_type_(static_cast<_value_type_ &&>(_value)); // NOLINT
new(OUTCOME_ADDRESS_OF(o._value)) _value_type_(static_cast<_value_type_ &&>(_value)); // NOLINT
if(!trait::is_move_bitcopying<value_type>::value)
{
this->_value.~value_type(); // NOLINT
Expand All @@ -1336,7 +1336,7 @@ namespace detail
if(o._status.have_value() && !_status.have_error())
{
// Move construct other into me
new(std::addressof(_value)) _value_type_(static_cast<_value_type_ &&>(o._value)); // NOLINT
new(OUTCOME_ADDRESS_OF(_value)) _value_type_(static_cast<_value_type_ &&>(o._value)); // NOLINT
if(!trait::is_move_bitcopying<value_type>::value)
{
o._value.~value_type(); // NOLINT
Expand All @@ -1347,7 +1347,7 @@ namespace detail
if(_status.have_error() && !o._status.have_value())
{
// Move construct me into other
new(std::addressof(o._error)) _error_type_(static_cast<_error_type_ &&>(_error)); // NOLINT
new(OUTCOME_ADDRESS_OF(o._error)) _error_type_(static_cast<_error_type_ &&>(_error)); // NOLINT
if(!trait::is_move_bitcopying<error_type>::value)
{
this->_error.~error_type(); // NOLINT
Expand All @@ -1358,7 +1358,7 @@ namespace detail
if(o._status.have_error() && !_status.have_value())
{
// Move construct other into me
new(std::addressof(_error)) _error_type_(static_cast<_error_type_ &&>(o._error)); // NOLINT
new(OUTCOME_ADDRESS_OF(_error)) _error_type_(static_cast<_error_type_ &&>(o._error)); // NOLINT
if(!trait::is_move_bitcopying<error_type>::value)
{
o._error.~error_type(); // NOLINT
Expand All @@ -1382,7 +1382,7 @@ namespace detail
this->b.set_have_lost_consistency(true);
}
}
} _{_status, o._status, std::addressof(_value), std::addressof(o._value), std::addressof(_error), std::addressof(o._error)};
} _{_status, o._status, OUTCOME_ADDRESS_OF(_value), OUTCOME_ADDRESS_OF(o._value), OUTCOME_ADDRESS_OF(_error), OUTCOME_ADDRESS_OF(o._error)};
if(_status.have_value() && o._status.have_error())
{
strong_placement(_.all_good, _.o_value, _.value, [&_] { //
Expand Down Expand Up @@ -1507,7 +1507,7 @@ namespace detail
}
if(!this->_status.have_value() && !this->_status.have_error() && o._status.have_value())
{
move_assign_to_empty<_value_type_>(std::addressof(this->_value), std::addressof(o._value));
move_assign_to_empty<_value_type_>(OUTCOME_ADDRESS_OF(this->_value), OUTCOME_ADDRESS_OF(o._value));
this->_status = o._status;
o._status.set_have_moved_from(true);
return *this;
Expand All @@ -1524,7 +1524,7 @@ namespace detail
}
if(!this->_status.have_value() && !this->_status.have_error() && o._status.have_error())
{
move_assign_to_empty<_error_type_>(std::addressof(this->_error), std::addressof(o._error));
move_assign_to_empty<_error_type_>(OUTCOME_ADDRESS_OF(this->_error), OUTCOME_ADDRESS_OF(o._error));
this->_status = o._status;
o._status.set_have_moved_from(true);
return *this;
Expand All @@ -1535,7 +1535,7 @@ namespace detail
{
this->_value.~_value_type_(); // NOLINT
}
move_assign_to_empty<_error_type_>(std::addressof(this->_error), std::addressof(o._error));
move_assign_to_empty<_error_type_>(OUTCOME_ADDRESS_OF(this->_error), OUTCOME_ADDRESS_OF(o._error));
this->_status = o._status;
o._status.set_have_moved_from(true);
return *this;
Expand All @@ -1546,7 +1546,7 @@ namespace detail
{
this->_error.~_error_type_(); // NOLINT
}
move_assign_to_empty<_value_type_>(std::addressof(this->_value), std::addressof(o._value));
move_assign_to_empty<_value_type_>(OUTCOME_ADDRESS_OF(this->_value), OUTCOME_ADDRESS_OF(o._value));
this->_status = o._status;
o._status.set_have_moved_from(true);
return *this;
Expand Down Expand Up @@ -1604,7 +1604,7 @@ namespace detail
}
if(!this->_status.have_value() && !this->_status.have_error() && o._status.have_value())
{
copy_assign_to_empty<_value_type_>(std::addressof(this->_value), std::addressof(o._value));
copy_assign_to_empty<_value_type_>(OUTCOME_ADDRESS_OF(this->_value), OUTCOME_ADDRESS_OF(o._value));
this->_status = o._status;
return *this;
}
Expand All @@ -1619,7 +1619,7 @@ namespace detail
}
if(!this->_status.have_value() && !this->_status.have_error() && o._status.have_error())
{
copy_assign_to_empty<_error_type_>(std::addressof(this->_error), std::addressof(o._error));
copy_assign_to_empty<_error_type_>(OUTCOME_ADDRESS_OF(this->_error), OUTCOME_ADDRESS_OF(o._error));
this->_status = o._status;
return *this;
}
Expand All @@ -1629,7 +1629,7 @@ namespace detail
{
this->_value.~_value_type_(); // NOLINT
}
copy_assign_to_empty<_error_type_>(std::addressof(this->_error), std::addressof(o._error));
copy_assign_to_empty<_error_type_>(OUTCOME_ADDRESS_OF(this->_error), OUTCOME_ADDRESS_OF(o._error));
this->_status = o._status;
return *this;
}
Expand All @@ -1639,7 +1639,7 @@ namespace detail
{
this->_error.~_error_type_(); // NOLINT
}
copy_assign_to_empty<_value_type_>(std::addressof(this->_value), std::addressof(o._value));
copy_assign_to_empty<_value_type_>(OUTCOME_ADDRESS_OF(this->_value), OUTCOME_ADDRESS_OF(o._value));
this->_status = o._status;
return *this;
}
Expand Down
6 changes: 6 additions & 0 deletions include/outcome/experimental/status_result.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ Distributed under the Boost Software License, Version 1.0.
#include "../basic_result.hpp"
#include "../policy/fail_to_compile_observers.hpp"

#ifndef SYSTEM_ERROR2_USE_STD_ADDRESSOF
#if OUTCOME_USE_STD_ADDRESSOF
#define SYSTEM_ERROR2_USE_STD_ADDRESSOF 1
#endif
#endif

#if __PCPP_ALWAYS_TRUE__
#include "status-code/include/status-code/system_error2.hpp"
#elif !OUTCOME_USE_SYSTEM_STATUS_CODE && __has_include("status-code/include/status-code/system_error2.hpp")
Expand Down
8 changes: 4 additions & 4 deletions include/outcome/iostream_support.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,12 @@ namespace detail
v._status.spare_storage_value = y;
if(v._status.have_value())
{
new(std::addressof(v._value)) decltype(v._value)(); // NOLINT
new(OUTCOME_ADDRESS_OF(v._value)) decltype(v._value)(); // NOLINT
s >> v._value; // NOLINT
}
if(v._status.have_error())
{
new(std::addressof(v._error)) decltype(v._error)(); // NOLINT
new(OUTCOME_ADDRESS_OF(v._error)) decltype(v._error)(); // NOLINT
s >> v._error; // NOLINT
}
return s;
Expand All @@ -103,7 +103,7 @@ namespace detail
v._status.spare_storage_value = y;
if(v._status.have_error())
{
new(std::addressof(v._error)) decltype(v._error)(); // NOLINT
new(OUTCOME_ADDRESS_OF(v._error)) decltype(v._error)(); // NOLINT
s >> v._error; // NOLINT
}
return s;
Expand All @@ -119,7 +119,7 @@ namespace detail
v._status.spare_storage_value = y;
if(v._status.have_value())
{
new(std::addressof(v._value)) decltype(v._value)(); // NOLINT
new(OUTCOME_ADDRESS_OF(v._value)) decltype(v._value)(); // NOLINT
s >> v._value; // NOLINT
}
return s;
Expand Down
Loading

0 comments on commit 0bedf67

Please sign in to comment.