mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-17 21:29:20 +00:00
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2976 91177308-0d34-0410-b5e6-96231b3b80d8
209 lines
4.7 KiB
C++
209 lines
4.7 KiB
C++
|
|
// (C) Copyright John Maddock 2000.
|
|
// Permission to copy, use, modify, sell and
|
|
// distribute this software is granted provided this copyright notice appears
|
|
// in all copies. This software is provided "as is" without express or implied
|
|
// warranty, and with no claim as to its suitability for any purpose.
|
|
|
|
//
|
|
// defines alignment_of:
|
|
|
|
#ifndef ALIGNMENT_TYPE_TRAITS_HPP
|
|
#define ALIGNMENT_TYPE_TRAITS_HPP
|
|
|
|
#include <cstdlib>
|
|
#include <cstddef>
|
|
#ifndef BOOST_ICE_TYPE_TRAITS_HPP
|
|
#include <boost/type_traits/ice.hpp>
|
|
#endif
|
|
#include <boost/preprocessor/list/for_each_i.hpp>
|
|
#include <boost/preprocessor/tuple/to_list.hpp>
|
|
#include <boost/preprocessor/cat.hpp>
|
|
#include <boost/type_traits/transform_traits.hpp>
|
|
#include <boost/static_assert.hpp>
|
|
|
|
#ifdef BOOST_MSVC
|
|
# pragma warning(push)
|
|
# pragma warning(disable: 4121) // alignment is sensitive to packing
|
|
#endif
|
|
|
|
namespace boost{
|
|
template <class T> struct alignment_of;
|
|
|
|
//
|
|
// get the alignment of some arbitrary type:
|
|
namespace detail{
|
|
|
|
template <class T>
|
|
struct alignment_of_hack
|
|
{
|
|
char c;
|
|
T t;
|
|
alignment_of_hack();
|
|
};
|
|
|
|
|
|
template <unsigned A, unsigned S>
|
|
struct alignment_logic
|
|
{
|
|
BOOST_STATIC_CONSTANT(std::size_t, value = A < S ? A : S);
|
|
};
|
|
|
|
} // namespace detail
|
|
|
|
template <class T>
|
|
struct alignment_of
|
|
{
|
|
BOOST_STATIC_CONSTANT(std::size_t, value =
|
|
(::boost::detail::alignment_logic<
|
|
sizeof(detail::alignment_of_hack<T>) - sizeof(T),
|
|
sizeof(T)
|
|
>::value));
|
|
};
|
|
|
|
//
|
|
// references have to be treated specially, assume
|
|
// that a reference is just a special pointer:
|
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
|
template <class T>
|
|
struct alignment_of<T&>
|
|
{
|
|
public:
|
|
BOOST_STATIC_CONSTANT(std::size_t, value = ::boost::alignment_of<T*>::value);
|
|
};
|
|
#endif
|
|
//
|
|
// void has to be treated specially:
|
|
template <>
|
|
struct alignment_of<void>
|
|
{ BOOST_STATIC_CONSTANT(std::size_t, value = 0); };
|
|
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
|
|
template <>
|
|
struct alignment_of<const void>
|
|
{ BOOST_STATIC_CONSTANT(std::size_t, value = 0); };
|
|
template <>
|
|
struct alignment_of<volatile void>
|
|
{ BOOST_STATIC_CONSTANT(std::size_t, value = 0); };
|
|
template <>
|
|
struct alignment_of<const volatile void>
|
|
{ BOOST_STATIC_CONSTANT(std::size_t, value = 0); };
|
|
#endif
|
|
|
|
namespace detail {
|
|
class alignment_dummy;
|
|
typedef void (*function_ptr)();
|
|
typedef int (alignment_dummy::*member_ptr);
|
|
typedef int (alignment_dummy::*member_function_ptr)();
|
|
|
|
/*
|
|
* The ct_if implementation is temporary code. It will be replaced with MPL
|
|
* in the future...
|
|
*/
|
|
struct select_then
|
|
{
|
|
template<typename Then, typename Else>
|
|
struct result
|
|
{
|
|
typedef Then type;
|
|
};
|
|
};
|
|
|
|
struct select_else
|
|
{
|
|
template<typename Then, typename Else>
|
|
struct result
|
|
{
|
|
typedef Else type;
|
|
};
|
|
};
|
|
|
|
template<bool Condition>
|
|
struct ct_if_selector
|
|
{
|
|
typedef select_then type;
|
|
};
|
|
|
|
template<>
|
|
struct ct_if_selector<false>
|
|
{
|
|
typedef select_else type;
|
|
};
|
|
|
|
template<bool Condition, typename Then, typename Else>
|
|
struct ct_if
|
|
{
|
|
typedef typename ct_if_selector<Condition>::type select;
|
|
typedef typename select::template result<Then,Else>::type type;
|
|
};
|
|
|
|
#define BOOST_TT_ALIGNMENT_TYPES BOOST_PP_TUPLE_TO_LIST( \
|
|
11, ( \
|
|
char, short, int, long, float, double, long double \
|
|
, void*, function_ptr, member_ptr, member_function_ptr))
|
|
|
|
#define BOOST_TT_CHOOSE_LOWER_ALIGNMENT(R,P,I,T) \
|
|
typename ct_if< \
|
|
alignment_of<T>::value <= target, T, char>::type BOOST_PP_CAT(t,I);
|
|
|
|
#define BOOST_TT_CHOOSE_T(R,P,I,T) T BOOST_PP_CAT(t,I);
|
|
|
|
template <std::size_t target>
|
|
union lower_alignment
|
|
{
|
|
BOOST_PP_LIST_FOR_EACH_I(
|
|
BOOST_TT_CHOOSE_LOWER_ALIGNMENT
|
|
, ignored, BOOST_TT_ALIGNMENT_TYPES)
|
|
};
|
|
|
|
union max_align
|
|
{
|
|
BOOST_PP_LIST_FOR_EACH_I(
|
|
BOOST_TT_CHOOSE_T
|
|
, ignored, BOOST_TT_ALIGNMENT_TYPES)
|
|
};
|
|
|
|
#undef BOOST_TT_ALIGNMENT_TYPES
|
|
#undef BOOST_TT_CHOOSE_LOWER_ALIGNMENT
|
|
#undef BOOST_TT_CHOOSE_T
|
|
|
|
template<int TAlign, int Align>
|
|
struct is_aligned
|
|
{
|
|
BOOST_STATIC_CONSTANT(bool,
|
|
value = (TAlign >= Align) & (TAlign % Align == 0));
|
|
};
|
|
|
|
}
|
|
|
|
// This alignment method originally due to Brian Parker, implemented by David
|
|
// Abrahams, and then ported here by Doug Gregor.
|
|
template <int Align>
|
|
class type_with_alignment
|
|
{
|
|
typedef detail::lower_alignment<Align> t1;
|
|
|
|
typedef type_with_alignment<Align> this_type;
|
|
|
|
typedef typename detail::ct_if<
|
|
(detail::is_aligned<(alignment_of<t1>::value), Align>::value)
|
|
, t1
|
|
, detail::max_align
|
|
>::type align_t;
|
|
|
|
BOOST_STATIC_CONSTANT(std::size_t, found = alignment_of<align_t>::value);
|
|
|
|
BOOST_STATIC_ASSERT(found >= Align);
|
|
BOOST_STATIC_ASSERT(found % Align == 0);
|
|
|
|
public:
|
|
typedef align_t type;
|
|
};
|
|
|
|
} // namespace boost
|
|
|
|
#ifdef BOOST_MSVC
|
|
# pragma warning(pop)
|
|
#endif
|
|
|
|
#endif // ALIGNMENT_TYPE_TRAITS_HPP
|