Skip to content

Commit

Permalink
deprecate accumulators::sum::small and ::large as workaround for bug …
Browse files Browse the repository at this point in the history
…in windows.h (#343)
  • Loading branch information
HDembinski committed Nov 15, 2021
1 parent dcd2315 commit f6577ec
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 17 deletions.
3 changes: 2 additions & 1 deletion include/boost/histogram/accumulators/ostream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
29 changes: 24 additions & 5 deletions include/boost/histogram/accumulators/sum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ class sum {

/// 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); }
Expand Down Expand Up @@ -96,10 +96,10 @@ class sum {
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(); }
Expand Down Expand Up @@ -156,6 +156,25 @@ class sum {

// 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_{};
Expand Down
3 changes: 2 additions & 1 deletion include/boost/histogram/algorithm/reduce.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
9 changes: 7 additions & 2 deletions include/boost/histogram/axis/traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 5 additions & 2 deletions include/boost/histogram/indexed.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ class BOOST_ATTRIBUTE_NODISCARD indexed_range {
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.
Expand All @@ -84,7 +86,8 @@ class BOOST_ATTRIBUTE_NODISCARD indexed_range {

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
Expand Down
8 changes: 6 additions & 2 deletions test/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -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 ;
Expand All @@ -176,3 +179,4 @@ explicit range ;
explicit units ;
explicit serialization ;
explicit libserial ;
explicit optional_boost ;
15 changes: 11 additions & 4 deletions test/accumulators_sum_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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};
Expand Down
6 changes: 6 additions & 0 deletions test/issue_327_test.cpp
Original file line number Diff line number Diff line change
@@ -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>
Expand Down
6 changes: 6 additions & 0 deletions test/odr_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down

0 comments on commit f6577ec

Please sign in to comment.