123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- #ifndef BOOST_NUMERIC_SAFE_BASE_HPP
- #define BOOST_NUMERIC_SAFE_BASE_HPP
- #include <limits>
- #include <type_traits>
- #include <boost/config.hpp>
- #include "concept/exception_policy.hpp"
- #include "concept/promotion_policy.hpp"
- #include "safe_common.hpp"
- #include "exception_policies.hpp"
- #include "boost/concept/assert.hpp"
- namespace boost {
- namespace safe_numerics {
- template<
- class Stored,
- Stored Min,
- Stored Max,
- class P, // promotion polic
- class E // exception policy
- >
- class safe_base;
- template<
- class T,
- T Min,
- T Max,
- class P,
- class E
- >
- struct is_safe<safe_base<T, Min, Max, P, E> > : public std::true_type
- {};
- template<
- class T,
- T Min,
- T Max,
- class P,
- class E
- >
- struct get_promotion_policy<safe_base<T, Min, Max, P, E> > {
- using type = P;
- };
- template<
- class T,
- T Min,
- T Max,
- class P,
- class E
- >
- struct get_exception_policy<safe_base<T, Min, Max, P, E> > {
- using type = E;
- };
- template<
- class T,
- T Min,
- T Max,
- class P,
- class E
- >
- struct base_type<safe_base<T, Min, Max, P, E> > {
- using type = T;
- };
- template<
- class T,
- T Min,
- T Max,
- class P,
- class E
- >
- constexpr T base_value(
- const safe_base<T, Min, Max, P, E> & st
- ) {
- return static_cast<T>(st);
- }
- template<
- typename T,
- T N,
- class P, // promotion policy
- class E // exception policy
- >
- class safe_literal_impl;
- #if BOOST_CLANG==1
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wmismatched-tags"
- #endif
- template<
- class Stored,
- Stored Min,
- Stored Max,
- class P, // promotion polic
- class E // exception policy
- >
- class safe_base {
- private:
- BOOST_CONCEPT_ASSERT((PromotionPolicy<P>));
- BOOST_CONCEPT_ASSERT((ExceptionPolicy<E>));
- Stored m_t;
- template<class T>
- constexpr Stored validated_cast(const T & t) const;
-
- template<class CharT, class Traits>
- void output(std::basic_ostream<CharT, Traits> & os) const;
-
-
-
-
-
-
-
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT, Traits> &
- operator<<(
- std::basic_ostream<CharT, Traits> & os,
- const safe_base & t
- ){
- t.output(os);
- return os;
- }
- template<class CharT, class Traits>
- void input(std::basic_istream<CharT, Traits> & is);
-
- template<class CharT, class Traits>
- friend inline std::basic_istream<CharT, Traits> &
- operator>>(
- std::basic_istream<CharT, Traits> & is,
- safe_base & t
- ){
- t.input(is);
- return is;
- }
-
- public:
-
-
- constexpr safe_base();
- struct skip_validation{};
- constexpr explicit safe_base(const Stored & rhs, skip_validation);
-
- template<
- class T,
- typename std::enable_if<
- std::is_convertible<T, Stored>::value,
- bool
- >::type = 0
- >
- constexpr safe_base(const T & t);
-
- template<typename T, T N, class Px, class Ex>
- constexpr safe_base(const safe_literal_impl<T, N, Px, Ex> & t);
-
-
- ~safe_base() = default;
-
- constexpr safe_base(const safe_base &) = default;
-
- constexpr safe_base & operator=(const safe_base &) = default;
-
- constexpr safe_base(safe_base &&) = default;
-
- constexpr safe_base & operator=(safe_base &&) = default;
-
-
-
-
-
-
- template<
- class R,
- typename std::enable_if<
- ! boost::safe_numerics::is_safe<R>::value,
- int
- >::type = 0
- >
- constexpr operator R () const;
-
-
- template<class T>
- constexpr safe_base &
- operator=(const T & rhs){
- m_t = validated_cast(rhs);
- return *this;
- }
-
- constexpr safe_base & operator++(){
- return *this = *this + 1;
- }
- constexpr safe_base & operator--(){
- return *this = *this - 1;
- }
- constexpr safe_base operator++(int){
- safe_base old_t = *this;
- ++(*this);
- return old_t;
- }
- constexpr safe_base operator--(int){
- safe_base old_t = *this;
- --(*this);
- return old_t;
- }
-
- constexpr auto operator+() const {
- return *this;
- }
-
-
-
-
- constexpr auto operator-() const {
-
-
-
-
-
- return 0 - *this;
- }
-
- constexpr auto operator~() const {
- return ~Stored(0u) ^ *this;
- }
- };
- }
- }
- #include <limits>
- namespace std {
- template<
- class T,
- T Min,
- T Max,
- class P,
- class E
- >
- class numeric_limits<boost::safe_numerics::safe_base<T, Min, Max, P, E> >
- : public std::numeric_limits<T>
- {
- using SB = boost::safe_numerics::safe_base<T, Min, Max, P, E>;
- public:
- constexpr static SB lowest() noexcept {
- return SB(Min, typename SB::skip_validation());
- }
- constexpr static SB min() noexcept {
- return SB(Min, typename SB::skip_validation());
- }
- constexpr static SB max() noexcept {
- return SB(Max, typename SB::skip_validation());
- }
- };
- }
- #if BOOST_CLANG==1
- #pragma GCC diagnostic pop
- #endif
- #endif
|