⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 truncation_test.hpp

📁 新版本TR1的stl
💻 HPP
📖 第 1 页 / 共 2 页
字号:
    char const  *FROM_  =   typeid(FROM).name();

    STLSOFT_SUPPRESS_UNUSED(TO_);
    STLSOFT_SUPPRESS_UNUSED(FROM_);
#endif /* _DEBUG */

    enum {  TO_is_signed            =   is_signed_type<TO>::value                   };
    enum {  FROM_is_signed          =   is_signed_type<FROM>::value                 };

    const ss_size_t sizeofFROM  =   sizeof(FROM);
    const ss_size_t sizeofTO    =   sizeof(TO);

    STLSOFT_SUPPRESS_UNUSED(sizeofFROM);
    STLSOFT_SUPPRESS_UNUSED(sizeofTO);

    STLSOFT_STATIC_ASSERT((0 == int(TO_is_signed)) != (0 == int(FROM_is_signed)));
    STLSOFT_STATIC_ASSERT(0 == int(FROM_is_signed));
    STLSOFT_STATIC_ASSERT(0 != int(TO_is_signed));

    // FROM is unsigned
    // TO is signed
    //
    // Truncation occurs if from > toMax

    FROM    toMax   =   static_cast<FROM>(limit_traits<TO>::maximum());

    if(from > toMax)
    {
        return false;
    }
    else
    {
        return true;
    }
}


template<   ss_typename_param_k TO
        ,   ss_typename_param_k FROM
        >
inline bool truncation_test_helper_runtime_test_same_sign(FROM from, yes_type, TO) // The use of the dummy variable is to fix a bug with VC++ 5-7.0
{
#ifdef _DEBUG
    char const  *TO_    =   typeid(TO).name();
    char const  *FROM_  =   typeid(FROM).name();

    STLSOFT_SUPPRESS_UNUSED(TO_);
    STLSOFT_SUPPRESS_UNUSED(FROM_);
#endif /* _DEBUG */

    const ss_size_t sizeofFROM  =   sizeof(FROM);
    const ss_size_t sizeofTO    =   sizeof(TO);

    STLSOFT_STATIC_ASSERT(sizeofTO < sizeofFROM);

    // This is a fully runtime test: does FROM fit into TO's limits?
    //
    // To do this we elicit TO's min and max. The values are held in
    // FROM, which involves no truncation because sizeof(FROM) > sizeof(TO)

    FROM    toMax   =   static_cast<FROM>(limit_traits<TO>::maximum());
    FROM    toMin   =   static_cast<FROM>(limit_traits<TO>::minimum());

    if( from < toMin ||
        from > toMax)
    {
        return false;
    }
    else
    {
        return true;
    }
}

template<   ss_typename_param_k TO
        ,   ss_typename_param_k FROM
        >
inline bool truncation_test_helper_runtime_test_same_sign(FROM from, no_type, TO)
{
#ifdef _DEBUG
    char const  *TO_    =   typeid(TO).name();
    char const  *FROM_  =   typeid(FROM).name();

    STLSOFT_SUPPRESS_UNUSED(TO_);
    STLSOFT_SUPPRESS_UNUSED(FROM_);
#endif /* _DEBUG */

    enum {  TO_is_signed            =   is_signed_type<TO>::value                   };
    enum {  FROM_is_signed          =   is_signed_type<FROM>::value                 };

    const ss_size_t sizeofFROM  =   sizeof(FROM);
    const ss_size_t sizeofTO    =   sizeof(TO);

    STLSOFT_SUPPRESS_UNUSED(sizeofFROM);
    STLSOFT_SUPPRESS_UNUSED(sizeofTO);

    STLSOFT_STATIC_ASSERT((0 == int(TO_is_signed)) != (0 == int(FROM_is_signed)));

    typedef ss_typename_param_k value_to_yesno_type<FROM_is_signed>::type  same_sign_yesno_t;

    return truncation_test_helper_runtime_test_different_sign_FROM_is_signed<TO>(from, same_sign_yesno_t(), TO());
}



template<   ss_typename_param_k TO
        ,   ss_typename_param_k FROM
        >
inline bool truncation_test_helper_runtime_test(FROM from, no_type, TO ) // The use of the dummy variable is to fix a bug with VC++ 5-7.0
{
#ifdef _DEBUG
    char const  *TO_    =   typeid(TO).name();
    char const  *FROM_  =   typeid(FROM).name();

    STLSOFT_SUPPRESS_UNUSED(TO_);
    STLSOFT_SUPPRESS_UNUSED(FROM_);
#endif /* _DEBUG */

    // Types are different

    // Next test for same sign
    enum {  TO_is_signed            =   is_signed_type<TO>::value                   };
    enum {  FROM_is_signed          =   is_signed_type<FROM>::value                 };

    enum {  types_have_same_sign    =   int(TO_is_signed) == int(FROM_is_signed)    };

    const ss_size_t sizeofFROM  =   sizeof(FROM);
    const ss_size_t sizeofTO    =   sizeof(TO);

    STLSOFT_STATIC_ASSERT(sizeofFROM >= sizeofTO || FROM_is_signed);

    typedef ss_typename_param_k value_to_yesno_type<types_have_same_sign>::type  same_sign_yesno_t;

    return truncation_test_helper_runtime_test_same_sign<TO>(from, same_sign_yesno_t(), TO());
}

template <typename T>
inline bool truncation_test_helper_runtime_test(T, yes_type, ...)
{
    return true;
}

#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */



template<   ss_typename_param_k TO
        ,   ss_typename_param_k FROM
        >
inline bool truncation_test_(FROM from, TO dummy = TO())    // The use of the dummy variable is to fix a bug with VC++ 5-7.0
{
#ifdef _DEBUG
    char const  *TO_    =   typeid(TO).name();
    char const  *FROM_  =   typeid(FROM).name();

    STLSOFT_SUPPRESS_UNUSED(TO_);
    STLSOFT_SUPPRESS_UNUSED(FROM_);
#endif /* _DEBUG */

    // First, we must check that the types are compatible, with constraints

    // Both types must be integral
    STLSOFT_STATIC_ASSERT(0 != is_integral_type<TO>::value);
    STLSOFT_STATIC_ASSERT(0 != is_integral_type<FROM>::value);

    // Now calculate the sizes

    const ss_size_t sizeofFROM  =   sizeof(FROM);
    const ss_size_t sizeofTO    =   sizeof(TO);

    // Now determine the signs

    enum {  TO_is_signed        =   is_signed_type<TO>::value           };
    enum {  FROM_is_signed      =   is_signed_type<FROM>::value         };

    // We know at compile time that FROM fits into TO if:
    //
    // - they have the same sign, and sizeof(FROM) <= sizeof(TO), OR
    // - FROM is unsigned (and TO is signed), and sizeof(FROM) < sizeof(TO)
    //
    // If either of these hold, then the answer is true: the yes_type overload
    //  of truncation_test_helper_runtime_test() is selected.
    //
    // If not, then a runtime test is required: the no_type overload
    //  of truncation_test_helper_runtime_test() is selected.

    enum { types_are_statically_compatible  =
                                                (   int(TO_is_signed) == int(FROM_is_signed) &&
                                                    sizeofFROM <= sizeofTO)
                                            ||
                                                (   !FROM_is_signed &&
                                                    sizeofFROM < sizeofTO)  };

    typedef ss_typename_param_k value_to_yesno_type<types_are_statically_compatible>::type  yesno_t;

    return truncation_test_helper_runtime_test<TO>(from, yesno_t(), dummy);
}


#if 0
template<ss_typename_param_k TO>
class truncation_test
{
public:
    template <ss_typename_param_k FROM>
    truncation_test(FROM from)
        : m_b(truncation_test_(from, get_to_()))
    {}

public:
    operator bool () const
    {
        return m_b;
    }

private:
    static TO get_to_()
    {
        return TO();
    }

private:
    const bool m_b;
};
#else /* ? 0 */
# define truncation_test    truncation_test_
#endif /* 0 */

////////////////////////////////////////////////////////////////////////////
// Unit-testing

#ifdef STLSOFT_UNITTEST
# include "./unittest/truncation_test_unittest_.h"
#endif /* STLSOFT_UNITTEST */

/* ////////////////////////////////////////////////////////////////////// */

#ifndef _STLSOFT_NO_NAMESPACE
} // namespace stlsoft
#endif /* _STLSOFT_NO_NAMESPACE */

/* ////////////////////////////////////////////////////////////////////// */

#endif /* !STLSOFT_INCL_STLSOFT_CONVERSION_HPP_TRUNCATION_TEST */

/* ////////////////////////////////////////////////////////////////////// */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -