Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/gil/promote_integral.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // Boost.GIL (Generic Image Library)
0002 //
0003 // Copyright (c) 2015, Oracle and/or its affiliates.
0004 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
0005 //
0006 // Copyright (c) 2020, Debabrata Mandal <mandaldebabrata123@gmail.com>
0007 //
0008 // Licensed under the Boost Software License version 1.0.
0009 // http://www.boost.org/users/license.html
0010 //
0011 // Source: Boost.Geometry (aka GGL, Generic Geometry Library)
0012 // Modifications: adapted for Boost.GIL
0013 //  - Rename namespace boost::geometry to boost::gil
0014 //  - Rename include guards
0015 //  - Remove support for boost::multiprecision types
0016 //  - Remove support for 128-bit integer types
0017 //  - Replace mpl meta functions with mp11 equivalents
0018 //
0019 #ifndef BOOST_GIL_PROMOTE_INTEGRAL_HPP
0020 #define BOOST_GIL_PROMOTE_INTEGRAL_HPP
0021 
0022 #include <boost/mp11/list.hpp>
0023 
0024 #include <climits>
0025 #include <cstddef>
0026 #include <type_traits>
0027 
0028 namespace boost { namespace gil
0029 {
0030 
0031 namespace detail { namespace promote_integral
0032 {
0033 
0034 // meta-function that returns the bit size of a type
0035 template
0036 <
0037     typename T,
0038     bool IsFundamental = std::is_fundamental<T>::value
0039 >
0040 struct bit_size {};
0041 
0042 // for fundamental types, just return CHAR_BIT * sizeof(T)
0043 template <typename T>
0044 struct bit_size<T, true> : std::integral_constant<std::size_t, (CHAR_BIT * sizeof(T))> {};
0045 
0046 template
0047 <
0048     typename T,
0049     typename IntegralTypes,
0050     std::size_t MinSize
0051 >
0052 struct promote_to_larger
0053 {
0054     using current_type = boost::mp11::mp_first<IntegralTypes>;
0055     using list_after_front = boost::mp11::mp_rest<IntegralTypes>;
0056 
0057     using type = typename std::conditional
0058         <
0059             (bit_size<current_type>::value >= MinSize),
0060             current_type,
0061             typename promote_to_larger
0062                 <
0063                     T,
0064                     list_after_front,
0065                     MinSize
0066                 >::type
0067         >::type;
0068 };
0069 
0070 // The following specialization is required to finish the loop over
0071 // all list elements
0072 template <typename T, std::size_t MinSize>
0073 struct promote_to_larger<T, boost::mp11::mp_list<>, MinSize>
0074 {
0075     // if promotion fails, keep the number T
0076     // (and cross fingers that overflow will not occur)
0077     using type = T;
0078 };
0079 
0080 }} // namespace detail::promote_integral
0081 
0082 /*!
0083     \brief Meta-function to define an integral type with size
0084     than is (roughly) twice the bit size of T
0085     \ingroup utility
0086     \details
0087     This meta-function tries to promote the fundamental integral type T
0088     to a another integral type with size (roughly) twice the bit size of T.
0089 
0090     To do this, two times the bit size of T is tested against the bit sizes of:
0091          short, int, long, boost::long_long_type, boost::int128_t
0092     and the one that first matches is chosen.
0093 
0094     For unsigned types the bit size of T is tested against the bit
0095     sizes of the types above, if T is promoted to a signed type, or
0096     the bit sizes of
0097          unsigned short, unsigned int, unsigned long, std::size_t,
0098          boost::ulong_long_type, boost::uint128_t
0099     if T is promoted to an unsigned type.
0100 
0101     By default an unsigned type is promoted to a signed type.
0102     This behavior is controlled by the PromoteUnsignedToUnsigned
0103     boolean template parameter, whose default value is "false".
0104     To promote an unsigned type to an unsigned type set the value of
0105     this template parameter to "true".
0106 
0107     Finally, if the passed type is either a floating-point type or a
0108     user-defined type it is returned as is.
0109 
0110     \note boost::long_long_type and boost::ulong_long_type are
0111     considered only if the macro BOOST_HAS_LONG_LONG is defined
0112 
0113 */
0114 template
0115 <
0116     typename T,
0117     bool PromoteUnsignedToUnsigned = false,
0118     bool UseCheckedInteger = false,
0119     bool IsIntegral = std::is_integral<T>::value
0120 >
0121 class promote_integral
0122 {
0123 private:
0124     static bool const is_unsigned = std::is_unsigned<T>::value;
0125 
0126     using bit_size_type = detail::promote_integral::bit_size<T>;
0127 
0128     // Define the minimum size (in bits) needed for the promoted type
0129     // If T is the input type and P the promoted type, then the
0130     // minimum number of bits for P are (below b stands for the number
0131     // of bits of T):
0132     // * if T is unsigned and P is unsigned: 2 * b
0133     // * if T is signed and P is signed: 2 * b - 1
0134     // * if T is unsigned and P is signed: 2 * b + 1
0135     using min_bit_size_type = typename std::conditional
0136         <
0137             (PromoteUnsignedToUnsigned && is_unsigned),
0138             std::integral_constant<std::size_t, (2 * bit_size_type::value)>,
0139             typename std::conditional
0140                 <
0141                     is_unsigned,
0142                     std::integral_constant<std::size_t, (2 * bit_size_type::value + 1)>,
0143                     std::integral_constant<std::size_t, (2 * bit_size_type::value - 1)>
0144                 >::type
0145         >::type;
0146 
0147     // Define the list of signed integral types we are going to use
0148     // for promotion
0149     using signed_integral_types = boost::mp11::mp_list
0150         <
0151             short, int, long
0152 #if defined(BOOST_HAS_LONG_LONG)
0153             , boost::long_long_type
0154 #endif
0155         >;
0156 
0157     // Define the list of unsigned integral types we are going to use
0158     // for promotion
0159     using unsigned_integral_types = boost::mp11::mp_list
0160         <
0161             unsigned short, unsigned int, unsigned long, std::size_t
0162 #if defined(BOOST_HAS_LONG_LONG)
0163             , boost::ulong_long_type
0164 #endif
0165         >;
0166 
0167     // Define the list of integral types that will be used for
0168     // promotion (depending in whether we was to promote unsigned to
0169     // unsigned or not)
0170     using integral_types = typename std::conditional
0171         <
0172             (is_unsigned && PromoteUnsignedToUnsigned),
0173             unsigned_integral_types,
0174             signed_integral_types
0175         >::type;
0176 
0177 public:
0178     using type = typename detail::promote_integral::promote_to_larger
0179         <
0180             T,
0181             integral_types,
0182             min_bit_size_type::value
0183         >::type;
0184 };
0185 
0186 
0187 template <typename T, bool PromoteUnsignedToUnsigned, bool UseCheckedInteger>
0188 class promote_integral
0189     <
0190         T, PromoteUnsignedToUnsigned, UseCheckedInteger, false
0191     >
0192 {
0193 public:
0194     using type = T;
0195 };
0196 
0197 }} // namespace boost::gil
0198 
0199 #endif // BOOST_GIL_PROMOTE_INTEGRAL_HPP