/* $Id: alignof_replacement.h,v 1.2 2004/01/25 22:43:13 wychen Exp $ */ /* -*-Mode: C;-*- */ /**************************************************************************** * alignof library * * Copyright (C) 2003 Martin Buchholz * * Permission to copy, use, sell and distribute this software is granted * provided this copyright notice appears in all copies. * Permission to modify the code and to distribute modified code is granted * provided this copyright notice appears in all copies, and a notice * that the code was modified is included with the copyright notice. * * This software is provided "as is" without express or implied warranty, * and with no claim as to its suitability for any purpose. * * * ---------------------------------------------------------------- * This code is known to work with the following compilers: * Linux x86 g++ 2.95 * Linux x86 g++ 3.2.1 * Linux x86 g++ 3.3 20030122 pre-release * Linux x86 g++ 3.4 20030122 pre-release * Linux x86 Intel compiler Version 7.0 * Windows x86 MS Visual C++ .NET Version 13.00 * * To work with MS Visual C++, we avoid partial template specialization. * ---------------------------------------------------------------- * * See: http://m17n.org/martin/writings/alignof.html * ****************************************************************************/ /**************************************************************************** * * $Source: bitbucket.org:berkeleylab/upc-translator.git/open64/osprey1.0/include/alignof_replacement.h $ * $Revision: 1.2 $ * $Date: 2004/01/25 22:43:13 $ * * Nathan Tallent: * - Brought into Open64 and made minor cosmetic changes. * - Converted initial comments into classic C comments (for non C99 * compilers). * * Description: * * This file provides a relatively portable C and C++ workaround for * the common compiler builtin alignof(). Note that because the C and * C++ versions are implemented quite differently, be careful about * assuming they will produce identical results. * * ALIGNOF (type) * Return alignment of TYPE. * * ALIGNOF_POD_TYPE (type) * Return a POD (Plain Ol' Data) type with the same alignment as TYPE. * ****************************************************************************/ #ifndef ALIGNOF_REPLACEMENT_HPP_INCLUDED_ #define ALIGNOF_REPLACEMENT_HPP_INCLUDED_ /****************************************************************************/ #if defined (__cplusplus) namespace Alignment { // Implementing alignof: // We compute alignof using two separate algorithms, then take their min. namespace ffs { // alignof (T) must be a power of two which is a factor of sizeof (T). template struct alignof { // Most common programmer interview question! enum { s = sizeof (T), value = s ^ (s & (s - 1)) }; }; } namespace QuantumJump { // Put T in a struct, keep adding chars until a "quantum jump" in // the size occurs. template struct alignof; template struct helper { template struct Val { enum { value = size_diff }; }; }; template <> struct helper<0> { template struct Val { enum { value = alignof::value }; }; }; template struct alignof { struct Big { T x; char c; }; enum { diff = sizeof (Big) - sizeof (T), value = helper::template Val::value }; }; } // QuantumJump template struct alignof { enum { x = QuantumJump::alignof::value, y = ffs::alignof::value, value = x < y ? x : y }; }; // ---------------------------------------------------------------- namespace POD { // Implementing alignpod: // We look for a POD type with the same alignment as a given C++ type T. // We first check a list of fundamental types. // In the unlikely event that that fails, // we check pointers to those types and structs containing those types. template struct equally_aligned { enum { value = ((int) alignof::value == (int) alignof::value) }; }; enum { TYPES_COUNT = 10 }; template struct types; struct Unknown; template struct types_helper { // This definition should be unnecessary, but makes MSVC happy template struct Val { typedef char Type; }; }; template <> struct types_helper { template struct Val { typedef typename types::Type BaseType; typedef BaseType* Type; }; }; template <> struct types_helper { template struct Val { typedef typename types::Type BaseType; struct Type { BaseType t; }; }; }; template struct types { enum { pointerify = ((n >= 1 * TYPES_COUNT) && (n < 2 * TYPES_COUNT)) }; enum { structify = ((n >= 2 * TYPES_COUNT) && (n < 3 * TYPES_COUNT)) }; typedef typename types_helper::template Val::Type Type; }; template <> struct types<0> { typedef char Type; }; template <> struct types<1> { typedef short Type; }; template <> struct types<2> { typedef int Type; }; template <> struct types<3> { typedef long Type; }; template <> struct types<4> { typedef float Type; }; template <> struct types<5> { typedef double Type; }; template <> struct types<6> { typedef long double Type; }; template <> struct types<7> { typedef void* Type; }; template <> struct types<8> { typedef void (*Type) (void); }; template <> struct types<9> { typedef Unknown (Unknown::*Type) (Unknown);}; namespace LinearSearch { template struct helper; template <> struct helper { template struct Val { typedef typename types::Type Type; }; }; template struct alignpod { typedef typename types::Type Candidate; enum { EQUALLY_ALIGNED = equally_aligned::value }; typedef typename helper::template Val::Type Type; }; template <> struct helper { template struct Val { typedef typename alignpod::Type Type; }; }; } // LinearSearch } // POD template struct alignpod { typedef typename POD::LinearSearch::alignpod::Type Type; }; } // Alignment #endif /* C++ */ /****************************************************************************/ /* gcc has an extension that gives us exactly what we want. We would use this in production code. #if defined (__GNUC__) && (__GNUC__ >= 2) #define ALIGNOF(type) __alignof__ (type) */ /* The following works with all known C++ compilers for POD types. It doesn't have the "inside out" declaration bug C does. But C++ forbids the use of offsetof with non-POD types. template struct alignment_trick { char c; T member; }; #define ALIGNOF(type) offsetof (alignment_trick, member) */ /* ALIGNOF (type) Return alignment of TYPE. */ #if defined (__cplusplus) /* C++ */ #define ALIGNOF(type) Alignment::alignof::value #else /* C */ /* The following is mostly portable, except that: - It doesn't work for inside out declarations like void (*) (void). (so just call ALIGNOF with a typedef'ed name) - It doesn't work with C++, not even with fundamental types. The C++ committee has decreed: "Types must be declared in declarations, not in expressions." */ #define ALIGNOF(type) offsetof (struct { char c; type member; }, member) #endif /* ALIGNOF_POD_TYPE (type) Return a POD (Plain Ol' Data) type with the same alignment as TYPE. */ #if defined (__cplusplus) /* C++ */ #define ALIGN_POD_TYPE(type) Alignment::alignpod::Type #else #define ALIGN_POD_TYPE(type) type #endif /****************************************************************************/ #endif // Recursive inclusion guard