Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:09:50

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Eric Niebler 2019-present
0005 //
0006 //  Use, modification and distribution is subject to the
0007 //  Boost Software License, Version 1.0. (See accompanying
0008 //  file LICENSE_1_0.txt or copy at
0009 //  http://www.boost.org/LICENSE_1_0.txt)
0010 //
0011 // Project home: https://github.com/ericniebler/range-v3
0012 //
0013 
0014 #ifndef RANGES_V3_ITERATOR_DIFFMAX_T_HPP
0015 #define RANGES_V3_ITERATOR_DIFFMAX_T_HPP
0016 
0017 #include <cstdint>
0018 #include <iosfwd>
0019 #include <limits>
0020 
0021 #include <concepts/concepts.hpp>
0022 
0023 #include <range/v3/range_fwd.hpp>
0024 
0025 #include <range/v3/iterator/concepts.hpp>
0026 
0027 #include <range/v3/detail/prologue.hpp>
0028 
0029 RANGES_DIAGNOSTIC_PUSH
0030 RANGES_DIAGNOSTIC_IGNORE_UNSIGNED_MATH
0031 
0032 namespace ranges
0033 {
0034     /// \cond
0035     namespace detail
0036     {
0037         struct diffmax_t
0038         {
0039         private:
0040             bool neg_;
0041             std::uintmax_t val_;
0042             struct tag
0043             {};
0044 
0045             constexpr diffmax_t(tag, bool neg, std::uintmax_t val)
0046               : neg_(val && neg)
0047               , val_(val)
0048             {}
0049 
0050             /// \cond
0051             constexpr void _check()
0052             {
0053                 RANGES_ENSURE(!neg_ || val_);
0054             }
0055             static constexpr diffmax_t _normalize(bool neg, std::uintmax_t val)
0056             {
0057                 return diffmax_t{tag{}, val && neg, val};
0058             }
0059             /// \endcond
0060 
0061         public:
0062             diffmax_t() = default;
0063 
0064             template(typename T)(
0065                 requires integral<T>)
0066             constexpr diffmax_t(T val) noexcept
0067               : neg_(0 > val)
0068               , val_(0 > val ? static_cast<std::uintmax_t>(-val)
0069                              : static_cast<std::uintmax_t>(val))
0070             {}
0071 
0072             friend constexpr bool operator<(diffmax_t a, diffmax_t b) noexcept
0073             {
0074                 a._check();
0075                 b._check();
0076                 return a.neg_ ? (b.neg_ ? a.val_ > b.val_ : true)
0077                               : (b.neg_ ? false : a.val_ < b.val_);
0078             }
0079             friend constexpr bool operator>(diffmax_t a, diffmax_t b) noexcept
0080             {
0081                 return b < a;
0082             }
0083             friend constexpr bool operator<=(diffmax_t a, diffmax_t b) noexcept
0084             {
0085                 return !(b < a);
0086             }
0087             friend constexpr bool operator>=(diffmax_t a, diffmax_t b) noexcept
0088             {
0089                 return !(a < b);
0090             }
0091             friend constexpr bool operator==(diffmax_t a, diffmax_t b) noexcept
0092             {
0093                 a._check();
0094                 b._check();
0095                 return a.val_ == b.val_ && a.neg_ == b.neg_;
0096             }
0097             friend constexpr bool operator!=(diffmax_t a, diffmax_t b) noexcept
0098             {
0099                 return !(a == b);
0100             }
0101 
0102             friend constexpr diffmax_t operator+(diffmax_t a) noexcept
0103             {
0104                 return a;
0105             }
0106             friend constexpr diffmax_t operator-(diffmax_t a) noexcept
0107             {
0108                 return _normalize(!a.neg_, a.val_);
0109             }
0110 
0111             friend constexpr diffmax_t operator+(diffmax_t a, diffmax_t b) noexcept
0112             {
0113                 return a.neg_ == b.neg_
0114                            ? diffmax_t{tag{}, a.neg_, a.val_ + b.val_}
0115                            : (a.neg_ ? (a.val_ > b.val_
0116                                             ? diffmax_t{tag{}, true, a.val_ - b.val_}
0117                                             : diffmax_t{tag{}, false, b.val_ - a.val_})
0118                                      : (b.val_ > a.val_
0119                                             ? diffmax_t{tag{}, true, b.val_ - a.val_}
0120                                             : diffmax_t{tag{}, false, a.val_ - b.val_}));
0121             }
0122             friend constexpr diffmax_t operator-(diffmax_t a, diffmax_t b) noexcept
0123             {
0124                 return a + -b;
0125             }
0126             friend constexpr diffmax_t operator*(diffmax_t a, diffmax_t b) noexcept
0127             {
0128                 return _normalize(a.neg_ ^ b.neg_, a.val_ * b.val_);
0129             }
0130             friend constexpr diffmax_t operator/(diffmax_t a, diffmax_t b) noexcept
0131             {
0132                 return _normalize(a.neg_ ^ b.neg_, a.val_ / b.val_);
0133             }
0134             friend constexpr diffmax_t operator%(diffmax_t a, diffmax_t b) noexcept
0135             {
0136                 return _normalize(a.neg_, a.val_ % b.val_);
0137             }
0138             static constexpr std::uintmax_t compl_if(bool neg,
0139                                                      std::uintmax_t val) noexcept
0140             {
0141                 return neg ? ~val + 1 : val;
0142             }
0143             friend constexpr diffmax_t operator&(diffmax_t a, diffmax_t b) noexcept
0144             {
0145                 return _normalize(
0146                     a.neg_ && b.neg_,
0147                     compl_if(a.neg_ && b.neg_,
0148                              compl_if(a.neg_, a.val_) & compl_if(b.neg_, b.val_)));
0149             }
0150             friend constexpr diffmax_t operator|(diffmax_t a, diffmax_t b) noexcept
0151             {
0152                 return _normalize(
0153                     a.neg_ || b.neg_,
0154                     compl_if(a.neg_ || b.neg_,
0155                              compl_if(a.neg_, a.val_) | compl_if(b.neg_, b.val_)));
0156             }
0157             friend constexpr diffmax_t operator^(diffmax_t a, diffmax_t b) noexcept
0158             {
0159                 return _normalize(
0160                     bool(a.neg_ ^ b.neg_),
0161                     compl_if(bool(a.neg_ ^ b.neg_),
0162                              compl_if(a.neg_, a.val_) ^ compl_if(b.neg_, b.val_)));
0163             }
0164 
0165             friend constexpr diffmax_t operator<<(diffmax_t a, diffmax_t b) noexcept
0166             {
0167                 RANGES_ENSURE(!a.neg_);
0168                 return b.neg_ ? diffmax_t{tag{}, false, a.val_ >> b.val_}
0169                               : diffmax_t{tag{}, false, a.val_ << b.val_};
0170             }
0171             friend constexpr diffmax_t operator>>(diffmax_t a, diffmax_t b) noexcept
0172             {
0173                 return b.neg_ ? diffmax_t{tag{}, a.neg_, a.val_ << b.val_}
0174                               : diffmax_t{tag{}, a.neg_, a.val_ >> b.val_};
0175             }
0176 
0177             friend constexpr diffmax_t & operator+=(diffmax_t & a, diffmax_t b) noexcept
0178             {
0179                 return (a = a + b);
0180             }
0181             friend constexpr diffmax_t & operator-=(diffmax_t & a, diffmax_t b) noexcept
0182             {
0183                 return (a = a - b);
0184             }
0185             friend constexpr diffmax_t & operator*=(diffmax_t & a, diffmax_t b) noexcept
0186             {
0187                 return (a = a * b);
0188             }
0189             friend constexpr diffmax_t & operator/=(diffmax_t & a, diffmax_t b) noexcept
0190             {
0191                 return (a = a / b);
0192             }
0193             friend constexpr diffmax_t & operator%=(diffmax_t & a, diffmax_t b) noexcept
0194             {
0195                 return (a = a % b);
0196             }
0197             friend constexpr diffmax_t & operator&=(diffmax_t & a, diffmax_t b) noexcept
0198             {
0199                 return (a = a & b);
0200             }
0201             friend constexpr diffmax_t & operator|=(diffmax_t & a, diffmax_t b) noexcept
0202             {
0203                 return (a = a | b);
0204             }
0205             friend constexpr diffmax_t & operator^=(diffmax_t & a, diffmax_t b) noexcept
0206             {
0207                 return (a = a ^ b);
0208             }
0209             friend constexpr diffmax_t & operator<<=(diffmax_t & a, diffmax_t b) noexcept
0210             {
0211                 a = (a << b);
0212                 return a;
0213             }
0214             friend constexpr diffmax_t & operator>>=(diffmax_t & a, diffmax_t b) noexcept
0215             {
0216                 a = (a >> b);
0217                 return a;
0218             }
0219 
0220             template<typename T>
0221             friend constexpr auto operator+=(T & a, diffmax_t b) noexcept
0222                 -> CPP_broken_friend_ret(T &)(
0223                     requires integral<T>)
0224             {
0225                 return (a = static_cast<T>(diffmax_t{a} + b));
0226             }
0227             template<typename T>
0228             friend constexpr auto operator-=(T & a, diffmax_t b) noexcept
0229                 -> CPP_broken_friend_ret(T &)(
0230                     requires integral<T>)
0231             {
0232                 return (a = static_cast<T>(diffmax_t{a} - b));
0233             }
0234             template<typename T>
0235             friend constexpr auto operator*=(T & a, diffmax_t b) noexcept
0236                 -> CPP_broken_friend_ret(T &)(
0237                     requires integral<T>)
0238             {
0239                 return (a = static_cast<T>(diffmax_t{a} * b));
0240             }
0241             template<typename T>
0242             friend constexpr auto operator/=(T & a, diffmax_t b) noexcept
0243                 -> CPP_broken_friend_ret(T &)(
0244                     requires integral<T>)
0245             {
0246                 return (a = static_cast<T>(diffmax_t{a} / b));
0247             }
0248             template<typename T>
0249             friend constexpr auto operator%=(T & a, diffmax_t b) noexcept
0250                 -> CPP_broken_friend_ret(T &)(
0251                     requires integral<T>)
0252             {
0253                 return (a = static_cast<T>(diffmax_t{a} % b));
0254             }
0255             template<typename T>
0256             friend constexpr auto operator&=(T & a, diffmax_t b) noexcept
0257                 -> CPP_broken_friend_ret(T &)(
0258                     requires integral<T>)
0259             {
0260                 return (a = static_cast<T>(diffmax_t{a} & b));
0261             }
0262             template<typename T>
0263             friend constexpr auto operator|=(T & a, diffmax_t b) noexcept
0264                 -> CPP_broken_friend_ret(T &)(
0265                     requires integral<T>)
0266             {
0267                 return (a = static_cast<T>(diffmax_t{a} | b));
0268             }
0269             template<typename T>
0270             friend constexpr auto operator^=(T & a, diffmax_t b) noexcept
0271                 -> CPP_broken_friend_ret(T &)(
0272                     requires integral<T>)
0273             {
0274                 return (a = static_cast<T>(diffmax_t{a} ^ b));
0275             }
0276             template<typename T>
0277             friend constexpr auto operator<<=(T & a, diffmax_t b) noexcept
0278                 -> CPP_broken_friend_ret(T &)(
0279                     requires integral<T>)
0280             {
0281                 a = static_cast<T>(diffmax_t{a} << b);
0282                 return a;
0283             }
0284             template<typename T>
0285             friend constexpr auto operator>>=(T & a, diffmax_t b) noexcept
0286                 -> CPP_broken_friend_ret(T &)(
0287                     requires integral<T>)
0288             {
0289                 a = static_cast<T>(diffmax_t{a} >> b);
0290                 return a;
0291             }
0292 
0293             friend constexpr diffmax_t & operator++(diffmax_t & a) noexcept
0294             {
0295                 a.neg_ = (a.neg_ ? --a.val_ : ++a.val_) && a.neg_;
0296                 return a;
0297             }
0298             friend constexpr diffmax_t & operator--(diffmax_t & a) noexcept
0299             {
0300                 a.neg_ = (a.neg_ ? ++a.val_ : --a.val_) && a.neg_;
0301                 return a;
0302             }
0303             friend constexpr diffmax_t operator++(diffmax_t & a, int) noexcept
0304             {
0305                 auto tmp = a;
0306                 ++a;
0307                 return tmp;
0308             }
0309             friend constexpr diffmax_t operator--(diffmax_t & a, int) noexcept
0310             {
0311                 auto tmp = a;
0312                 --a;
0313                 return tmp;
0314             }
0315 
0316             template(typename T)(
0317                 requires integral<T>)
0318                 constexpr explicit
0319                 operator T() const noexcept
0320             {
0321                 return neg_ ? -static_cast<T>(val_) : static_cast<T>(val_);
0322             }
0323             constexpr explicit operator bool() const noexcept
0324             {
0325                 return val_ != 0;
0326             }
0327             constexpr bool operator!() const noexcept
0328             {
0329                 return val_ == 0;
0330             }
0331 
0332             template<typename Ostream>
0333             friend auto operator<<(Ostream & sout, diffmax_t a)
0334                 -> CPP_broken_friend_ret(std::ostream &)(
0335                     requires derived_from<
0336                         Ostream, std::basic_ostream<typename Ostream::char_type,
0337                                                     typename Ostream::traits_type>>)
0338             {
0339                 return sout << (&"-"[!a.neg_]) << a.val_;
0340             }
0341         };
0342 
0343 #if RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
0344         template<>
0345         inline constexpr bool _is_integer_like_<diffmax_t> = true;
0346 #else
0347         template<typename Enable>
0348         constexpr bool _is_integer_like_<diffmax_t, Enable> = true;
0349 #endif
0350     } // namespace detail
0351     /// \endcond
0352 } // namespace ranges
0353 
0354 /// \cond
0355 RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS
0356 
0357 namespace std
0358 {
0359     template<>
0360     struct numeric_limits<::ranges::detail::diffmax_t>
0361     {
0362         static constexpr bool is_specialized = true;
0363         static constexpr bool is_signed = true;
0364         static constexpr bool is_integer = true;
0365         static constexpr bool is_exact = true;
0366         static constexpr bool has_infinity = false;
0367         static constexpr bool has_quiet_NaN = false;
0368         static constexpr bool has_signaling_NaN = false;
0369         static constexpr bool has_denorm = false;
0370         static constexpr bool has_denorm_loss = false;
0371         static constexpr std::float_round_style round_style = std::round_toward_zero;
0372         static constexpr bool is_iec559 = false;
0373         static constexpr bool is_bounded = true;
0374         static constexpr bool is_modulo = false;
0375         static constexpr int digits = CHAR_BIT * sizeof(std::uintmax_t) + 1;
0376         static constexpr int digits10 =
0377             static_cast<int>(digits * 0.301029996); // digits * std::log10(2)
0378         static constexpr int max_digits10 = 0;
0379         static constexpr int radix = 2;
0380         static constexpr int min_exponent = 0;
0381         static constexpr int min_exponent10 = 0;
0382         static constexpr int max_exponent = 0;
0383         static constexpr int max_exponent10 = 0;
0384         static constexpr bool traps = true;
0385         static constexpr bool tinyness_before = false;
0386 
0387         static constexpr ::ranges::detail::diffmax_t max() noexcept
0388         {
0389             return std::uintmax_t(-1);
0390         }
0391         static constexpr ::ranges::detail::diffmax_t min() noexcept
0392         {
0393             return -max();
0394         }
0395         static constexpr ::ranges::detail::diffmax_t lowest() noexcept
0396         {
0397             return min();
0398         }
0399         static constexpr ::ranges::detail::diffmax_t epsilon() noexcept
0400         {
0401             return 0;
0402         }
0403         static constexpr ::ranges::detail::diffmax_t round_error() noexcept
0404         {
0405             return 0;
0406         }
0407         static constexpr ::ranges::detail::diffmax_t infinity() noexcept
0408         {
0409             return 0;
0410         }
0411         static constexpr ::ranges::detail::diffmax_t quiet_NaN() noexcept
0412         {
0413             return 0;
0414         }
0415         static constexpr ::ranges::detail::diffmax_t signaling_NaN() noexcept
0416         {
0417             return 0;
0418         }
0419         static constexpr ::ranges::detail::diffmax_t denorm_min() noexcept
0420         {
0421             return 0;
0422         }
0423     };
0424     template<>
0425     struct numeric_limits<::ranges::detail::diffmax_t const>
0426       : numeric_limits<::ranges::detail::diffmax_t>
0427     {};
0428     template<>
0429     struct numeric_limits<::ranges::detail::diffmax_t volatile>
0430       : numeric_limits<::ranges::detail::diffmax_t>
0431     {};
0432     template<>
0433     struct numeric_limits<::ranges::detail::diffmax_t const volatile>
0434       : numeric_limits<::ranges::detail::diffmax_t>
0435     {};
0436 
0437 #if RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
0438     inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::is_specialized;
0439     inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::is_signed;
0440     inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::is_integer;
0441     inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::is_exact;
0442     inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::has_infinity;
0443     inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::has_quiet_NaN;
0444     inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::has_signaling_NaN;
0445     inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::has_denorm;
0446     inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::has_denorm_loss;
0447     inline constexpr std::float_round_style
0448         numeric_limits<::ranges::detail::diffmax_t>::round_style;
0449     inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::is_iec559;
0450     inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::is_bounded;
0451     inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::is_modulo;
0452     inline constexpr int numeric_limits<::ranges::detail::diffmax_t>::digits;
0453     inline constexpr int numeric_limits<::ranges::detail::diffmax_t>::digits10;
0454     inline constexpr int numeric_limits<::ranges::detail::diffmax_t>::max_digits10;
0455     inline constexpr int numeric_limits<::ranges::detail::diffmax_t>::radix;
0456     inline constexpr int numeric_limits<::ranges::detail::diffmax_t>::min_exponent;
0457     inline constexpr int numeric_limits<::ranges::detail::diffmax_t>::min_exponent10;
0458     inline constexpr int numeric_limits<::ranges::detail::diffmax_t>::max_exponent;
0459     inline constexpr int numeric_limits<::ranges::detail::diffmax_t>::max_exponent10;
0460     inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::traps;
0461     inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::tinyness_before;
0462 #endif
0463 } // namespace std
0464 /// \endcond
0465 
0466 RANGES_DIAGNOSTIC_POP
0467 
0468 #include <range/v3/detail/epilogue.hpp>
0469 
0470 #endif