mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-07 16:07:53 +00:00
Added thirdparty: boost library
This commit is contained in:
+217
@@ -0,0 +1,217 @@
|
||||
#ifndef BOOST_NUMERIC_CHECKED_DEFAULT_HPP
|
||||
#define BOOST_NUMERIC_CHECKED_DEFAULT_HPP
|
||||
|
||||
// Copyright (c) 2017 Robert Ramey
|
||||
//
|
||||
// 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)
|
||||
|
||||
// contains operation implementation of arithmetic operators
|
||||
// on built-in types. The default implementation is to just
|
||||
// invoke the operation with no checking. These are overloaded
|
||||
// for specific types such as integer, etc.
|
||||
|
||||
// implement the equivant of template partial specialization for functions
|
||||
|
||||
// what we need is
|
||||
// a) a default implementation of add, subtract, etc which just
|
||||
// implements the standard operations and returns the result
|
||||
// b) specific implementations to be called from safe implementation
|
||||
// such as safe<int> ... and someday maybe money<T, D> ...
|
||||
//
|
||||
// What we need is partial function specialization - but this doesn't
|
||||
// exist in C++ (yet?). But particial specialization of structures DOES
|
||||
// exist. So put our functions into a class which can then be
|
||||
// partially specialized. Finally. add a function interface to so that
|
||||
// data types can be deduced from the function call. We now have
|
||||
// the equivalent of partial function template specialization.
|
||||
|
||||
// usage example: checked<int>::add(t, u) ...
|
||||
|
||||
#include <boost/logic/tribool.hpp>
|
||||
#include "checked_result.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace safe_numerics {
|
||||
|
||||
// main function object which contains functions which handle
|
||||
// primitives which haven't been overriden. For now, these
|
||||
// implement the default operation. But I see this as an indicator
|
||||
// that there is more work to be done. For example float * int should
|
||||
// never be called because promotions on operands should occur before
|
||||
// the operation is invoked. So rather than returning the default operation
|
||||
// it should trap with a static_assert. This occurs at compile time while
|
||||
// calculating result interval. This needs more investigation.
|
||||
|
||||
template<
|
||||
typename R,
|
||||
R Min,
|
||||
R Max,
|
||||
typename T,
|
||||
class F = make_checked_result<R>,
|
||||
class Default = void
|
||||
>
|
||||
struct heterogeneous_checked_operation {
|
||||
constexpr static checked_result<R>
|
||||
cast(const T & t) /* noexcept */ {
|
||||
return static_cast<R>(t);
|
||||
}
|
||||
};
|
||||
|
||||
template<
|
||||
typename R,
|
||||
class F = make_checked_result<R>,
|
||||
class Default = void
|
||||
>
|
||||
struct checked_operation{
|
||||
constexpr static checked_result<R>
|
||||
minus(const R & t) noexcept {
|
||||
return - t;
|
||||
}
|
||||
constexpr static checked_result<R>
|
||||
add(const R & t, const R & u) noexcept {
|
||||
return t + u;
|
||||
}
|
||||
constexpr static checked_result<R>
|
||||
subtract(const R & t, const R & u) noexcept {
|
||||
return t - u;
|
||||
}
|
||||
constexpr static checked_result<R>
|
||||
multiply(const R & t, const R & u) noexcept {
|
||||
return t * u;
|
||||
}
|
||||
constexpr static checked_result<R>
|
||||
divide(const R & t, const R & u) noexcept {
|
||||
return t / u;
|
||||
}
|
||||
constexpr static checked_result<R>
|
||||
modulus(const R & t, const R & u) noexcept {
|
||||
return t % u;
|
||||
}
|
||||
constexpr static boost::logic::tribool
|
||||
less_than(const R & t, const R & u) noexcept {
|
||||
return t < u;
|
||||
}
|
||||
constexpr static boost::logic::tribool
|
||||
greater_than(const R & t, const R & u) noexcept {
|
||||
return t > u;
|
||||
}
|
||||
constexpr static boost::logic::tribool
|
||||
equal(const R & t, const R & u) noexcept {
|
||||
return t < u;
|
||||
}
|
||||
constexpr static checked_result<R>
|
||||
left_shift(const R & t, const R & u) noexcept {
|
||||
return t << u;
|
||||
}
|
||||
constexpr static checked_result<R>
|
||||
right_shift(const R & t, const R & u) noexcept {
|
||||
return t >> u;
|
||||
}
|
||||
constexpr static checked_result<R>
|
||||
bitwise_or(const R & t, const R & u) noexcept {
|
||||
return t | u;
|
||||
}
|
||||
constexpr static checked_result<R>
|
||||
bitwise_xor(const R & t, const R & u) noexcept {
|
||||
return t ^ u;
|
||||
}
|
||||
constexpr static checked_result<R>
|
||||
bitwise_and(const R & t, const R & u) noexcept {
|
||||
return t & u;
|
||||
}
|
||||
constexpr static checked_result<R>
|
||||
bitwise_not(const R & t) noexcept {
|
||||
return ~t;
|
||||
}
|
||||
};
|
||||
|
||||
namespace checked {
|
||||
|
||||
// implement function call interface so that types other than
|
||||
// the result type R can be deduced from the function parameters.
|
||||
|
||||
template<typename R, typename T>
|
||||
constexpr inline checked_result<R> cast(const T & t) /* noexcept */ {
|
||||
return heterogeneous_checked_operation<
|
||||
R,
|
||||
std::numeric_limits<R>::min(),
|
||||
std::numeric_limits<R>::max(),
|
||||
T
|
||||
>::cast(t);
|
||||
}
|
||||
template<typename R>
|
||||
constexpr inline checked_result<R> minus(const R & t) noexcept {
|
||||
return checked_operation<R>::minus(t);
|
||||
}
|
||||
template<typename R>
|
||||
constexpr inline checked_result<R> add(const R & t, const R & u) noexcept {
|
||||
return checked_operation<R>::add(t, u);
|
||||
}
|
||||
template<typename R>
|
||||
constexpr inline checked_result<R> subtract(const R & t, const R & u) noexcept {
|
||||
return checked_operation<R>::subtract(t, u);
|
||||
}
|
||||
template<typename R>
|
||||
constexpr inline checked_result<R> multiply(const R & t, const R & u) noexcept {
|
||||
return checked_operation<R>::multiply(t, u);
|
||||
}
|
||||
template<typename R>
|
||||
constexpr inline checked_result<R> divide(const R & t, const R & u) noexcept {
|
||||
return checked_operation<R>::divide(t, u);
|
||||
}
|
||||
template<typename R>
|
||||
constexpr inline checked_result<R> modulus(const R & t, const R & u) noexcept {
|
||||
return checked_operation<R>::modulus(t, u);
|
||||
}
|
||||
template<typename R>
|
||||
constexpr inline checked_result<bool> less_than(const R & t, const R & u) noexcept {
|
||||
return checked_operation<R>::less_than(t, u);
|
||||
}
|
||||
template<typename R>
|
||||
constexpr inline checked_result<bool> greater_than_equal(const R & t, const R & u) noexcept {
|
||||
return ! checked_operation<R>::less_than(t, u);
|
||||
}
|
||||
template<typename R>
|
||||
constexpr inline checked_result<bool> greater_than(const R & t, const R & u) noexcept {
|
||||
return checked_operation<R>::greater_than(t, u);
|
||||
}
|
||||
template<typename R>
|
||||
constexpr inline checked_result<bool> less_than_equal(const R & t, const R & u) noexcept {
|
||||
return ! checked_operation<R>::greater_than(t, u);
|
||||
}
|
||||
template<typename R>
|
||||
constexpr inline checked_result<bool> equal(const R & t, const R & u) noexcept {
|
||||
return checked_operation<R>::equal(t, u);
|
||||
}
|
||||
template<typename R>
|
||||
constexpr inline checked_result<R> left_shift(const R & t, const R & u) noexcept {
|
||||
return checked_operation<R>::left_shift(t, u);
|
||||
}
|
||||
template<typename R>
|
||||
constexpr inline checked_result<R> right_shift(const R & t, const R & u) noexcept {
|
||||
return checked_operation<R>::right_shift(t, u);
|
||||
}
|
||||
template<typename R>
|
||||
constexpr inline checked_result<R> bitwise_or(const R & t, const R & u) noexcept {
|
||||
return checked_operation<R>::bitwise_or(t, u);
|
||||
}
|
||||
template<typename R>
|
||||
constexpr inline checked_result<R> bitwise_xor(const R & t, const R & u) noexcept {
|
||||
return checked_operation<R>::bitwise_xor(t, u);
|
||||
}
|
||||
template<typename R>
|
||||
constexpr inline checked_result<R> bitwise_and(const R & t, const R & u) noexcept {
|
||||
return checked_operation<R>::bitwise_and(t, u);
|
||||
}
|
||||
template<typename R>
|
||||
constexpr inline checked_result<R> bitwise_not(const R & t) noexcept {
|
||||
return checked_operation<R>::bitwise_not(t);
|
||||
}
|
||||
|
||||
} // checked
|
||||
} // safe_numerics
|
||||
} // boost
|
||||
|
||||
#endif // BOOST_NUMERIC_CHECKED_DEFAULT_HPP
|
||||
Reference in New Issue
Block a user