deprecate accumulators::sum::small and ::large as workaround for bug in windows.h (#343)

This commit is contained in:
Hans Dembinski 2021-09-30 11:20:56 +02:00 committed by Hans Dembinski
parent dcd2315e6b
commit f6577ec473
9 changed files with 69 additions and 17 deletions

View File

@ -63,7 +63,8 @@ std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>&
template <class CharT, class Traits, class U>
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os,
const sum<U>& x) {
if (os.width() == 0) return os << "sum(" << x.large() << " + " << x.small() << ")";
if (os.width() == 0)
return os << "sum(" << x.large_part() << " + " << x.small_part() << ")";
return detail::handle_nonzero_width(os, x);
}

View File

@ -43,11 +43,11 @@ public:
/// Allow implicit conversion from sum<T>
template <class T>
sum(const sum<T>& s) noexcept : sum(s.large(), s.small()) {}
sum(const sum<T>& s) noexcept : sum(s.large_part(), s.small_part()) {}
/// Initialize sum explicitly with large and small parts
sum(const_reference large, const_reference small) noexcept
: large_(large), small_(small) {}
sum(const_reference large_part, const_reference small_part) noexcept
: large_(large_part), small_(small_part) {}
/// Increment sum by one
sum& operator++() noexcept { return operator+=(1); }
@ -96,10 +96,10 @@ public:
value_type value() const noexcept { return large_ + small_; }
/// Return large part of the sum.
const_reference large() const noexcept { return large_; }
const_reference large_part() const noexcept { return large_; }
/// Return small part of the sum.
const_reference small() const noexcept { return small_; }
const_reference small_part() const noexcept { return small_; }
// lossy conversion to value type must be explicit
explicit operator value_type() const noexcept { return value(); }
@ -156,6 +156,25 @@ public:
// end: extra operators
// windows.h illegially uses `#define small char` which breaks this now deprecated API
#if !defined(small)
/// Return large part of the sum.
[[deprecated("use large_part() instead; "
"large() will be removed in boost-1.80")]] const_reference
large() const noexcept {
return large_;
}
/// Return small part of the sum.
[[deprecated("use small_part() instead; "
"small() will be removed in boost-1.80")]] const_reference
small() const noexcept {
return small_;
}
#endif
private:
value_type large_{};
value_type small_{};

View File

@ -33,7 +33,8 @@ namespace algorithm {
*/
using reduce_command = detail::reduce_command;
using reduce_option [[deprecated("use reduce_command instead")]] =
using reduce_option [[deprecated("use reduce_command instead; "
"reduce_option will be removed in boost-1.80")]] =
reduce_command; ///< deprecated
/** Shrink command to be used in `reduce`.

View File

@ -194,7 +194,9 @@ template <class Axis>
using get_options = decltype(detail::traits_options<Axis>(detail::priority<2>{}));
template <class Axis>
using static_options [[deprecated("use get_options instead")]] = get_options<Axis>;
using static_options [[deprecated("use get_options instead; "
"static_options will be removed in boost-1.80")]] =
get_options<Axis>;
#else
struct get_options;
@ -223,7 +225,10 @@ template <class Axis>
using is_inclusive = decltype(detail::traits_is_inclusive<Axis>(detail::priority<1>{}));
template <class Axis>
using static_is_inclusive [[deprecated("use is_inclusive instead")]] = is_inclusive<Axis>;
using static_is_inclusive
[[deprecated("use is_inclusive instead; "
"static_is_inclusive will be removed in boost-1.80")]] =
is_inclusive<Axis>;
#else
struct is_inclusive;

View File

@ -64,7 +64,9 @@ public:
using value_type = typename std::iterator_traits<value_iterator>::value_type;
class iterator;
using range_iterator [[deprecated("use iterator instead")]] = iterator; ///< deprecated
using range_iterator [[deprecated("use iterator instead; "
"range_iterator will be removed in boost-1.80")]] =
iterator; ///< deprecated
/** Lightweight view to access value and index of current cell.
@ -84,7 +86,8 @@ public:
public:
using const_reference = const axis::index_type&;
using reference [[deprecated("use const_reference instead")]] =
using reference [[deprecated("use const_reference instead; "
"reference will be removed in boost-1.80")]] =
const_reference; ///< deprecated
/// implementation detail

View File

@ -157,11 +157,14 @@ alias libserial :
# for builds without optional boost dependencies
alias minimal : cxx14 cxx17 failure threading ;
# for builds with optional boost dependencies
alias optional_boost : accumulators range units serialization ;
# all tests
alias all : minimal not_windows odr accumulators range units serialization ;
alias all : minimal not_windows odr optional_boost ;
# all except "failure", because it is distracting during development
alias develop : cxx14 cxx17 threading not_windows odr accumulators range units serialization ;
alias develop : odr cxx14 cxx17 threading not_windows optional_boost ;
explicit minimal ;
explicit all ;
@ -176,3 +179,4 @@ explicit range ;
explicit units ;
explicit serialization ;
explicit libserial ;
explicit optional_boost ;

View File

@ -26,12 +26,19 @@ int main() {
++sum;
BOOST_TEST_EQ(sum, 1);
BOOST_TEST_EQ(sum.value(), 1);
BOOST_TEST_EQ(sum.large(), 1);
BOOST_TEST_EQ(sum.small(), 0);
BOOST_TEST_EQ(sum.large_part(), 1);
BOOST_TEST_EQ(sum.small_part(), 0);
BOOST_TEST_EQ(str(sum), "sum(1 + 0)"s);
BOOST_TEST_EQ(str(sum, 15, false), " sum(1 + 0)"s);
BOOST_TEST_EQ(str(sum, 15, true), "sum(1 + 0) "s);
#include <boost/histogram/detail/ignore_deprecation_warning_begin.hpp>
BOOST_TEST_EQ(sum.large(), 1);
BOOST_TEST_EQ(sum.small(), 0);
#include <boost/histogram/detail/ignore_deprecation_warning_end.hpp>
sum += 1e100;
BOOST_TEST_EQ(sum, (s_t{1e100, 1}));
++sum;
@ -40,8 +47,8 @@ int main() {
BOOST_TEST_EQ(sum, (s_t{0, 2}));
BOOST_TEST_EQ(sum, 2); // correct answer
BOOST_TEST_EQ(sum.value(), 2);
BOOST_TEST_EQ(sum.large(), 0);
BOOST_TEST_EQ(sum.small(), 2);
BOOST_TEST_EQ(sum.large_part(), 0);
BOOST_TEST_EQ(sum.small_part(), 2);
sum = s_t{1e100, 1};
sum += s_t{1e100, 1};

View File

@ -1,3 +1,9 @@
// Copyright 2021 Hans Dembinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/core/lightweight_test.hpp>
#include <boost/histogram.hpp>
#include <boost/histogram/ostream.hpp>

View File

@ -4,6 +4,12 @@
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
// The header windows.h and possibly others illegially do the following
#define small char
// which violates the C++ standard. We make sure here that including our headers work
// nevertheless by avoiding the preprocessing token `small`. For more details, see
// https://github.com/boostorg/histogram/issues/342
// include all Boost.Histogram header here; see odr_main_test.cpp for details
#include <boost/histogram.hpp>
#include <boost/histogram/ostream.hpp>