146 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			146 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C++
		
	
	
	
| #ifndef MY_COMPILER_INCLUDED
 | |
| #define MY_COMPILER_INCLUDED
 | |
| 
 | |
| /* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
 | |
| 
 | |
|    This program is free software; you can redistribute it and/or modify
 | |
|    it under the terms of the GNU General Public License as published by
 | |
|    the Free Software Foundation; version 2 of the License.
 | |
| 
 | |
|    This program is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|    GNU General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU General Public License
 | |
|    along with this program; if not, write to the Free Software
 | |
|    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
 | |
| 
 | |
| /**
 | |
|   Header for compiler-dependent features.
 | |
| 
 | |
|   Intended to contain a set of reusable wrappers for preprocessor
 | |
|   macros, attributes, pragmas, and any other features that are
 | |
|   specific to a target compiler.
 | |
| */
 | |
| 
 | |
| #include <my_global.h>                          /* stddef.h offsetof */
 | |
| 
 | |
| /**
 | |
|   Compiler-dependent internal convenience macros.
 | |
| */
 | |
| 
 | |
| /* GNU C/C++ */
 | |
| #if defined __GNUC__
 | |
| /* Convenience macro to test the minimum required GCC version. */
 | |
| # define MY_GNUC_PREREQ(maj, min) \
 | |
|     ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
 | |
| /* Any after 2.95... */
 | |
| # define MY_ALIGN_EXT
 | |
| /* Comunicate to the compiler the unreachability of the code. */
 | |
| # if MY_GNUC_PREREQ(4,5)
 | |
| #   define MY_ASSERT_UNREACHABLE()   __builtin_unreachable()
 | |
| # endif
 | |
| 
 | |
| /* Microsoft Visual C++ */
 | |
| #elif defined _MSC_VER
 | |
| # define MY_ALIGNOF(type)   __alignof(type)
 | |
| # define MY_ALIGNED(n)      __declspec(align(n))
 | |
| 
 | |
| /* Oracle Solaris Studio */
 | |
| #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
 | |
| # if __SUNPRO_C >= 0x590
 | |
| #   define MY_ALIGN_EXT
 | |
| # endif
 | |
| 
 | |
| /* IBM XL C/C++ */
 | |
| #elif defined __xlC__
 | |
| # if __xlC__ >= 0x0600
 | |
| #   define MY_ALIGN_EXT
 | |
| # endif
 | |
| 
 | |
| /* HP aCC */
 | |
| #elif defined(__HP_aCC) || defined(__HP_cc)
 | |
| # if (__HP_aCC >= 60000) || (__HP_cc >= 60000)
 | |
| #   define MY_ALIGN_EXT
 | |
| # endif
 | |
| #endif
 | |
| 
 | |
| #ifdef MY_ALIGN_EXT
 | |
| /** Specifies the minimum alignment of a type. */
 | |
| # define MY_ALIGNOF(type)   __alignof__(type)
 | |
| /** Determine the alignment requirement of a type. */
 | |
| # define MY_ALIGNED(n)      __attribute__((__aligned__((n))))
 | |
| #endif
 | |
| 
 | |
| /**
 | |
|   Generic (compiler-independent) features.
 | |
| */
 | |
| 
 | |
| #ifndef MY_GNUC_PREREQ
 | |
| # define MY_GNUC_PREREQ(maj, min) (0)
 | |
| #endif
 | |
| 
 | |
| #ifndef MY_ALIGNOF
 | |
| # ifdef __cplusplus
 | |
|     template<typename type> struct my_alignof_helper { char m1; type m2; };
 | |
|     /* Invalid for non-POD types, but most compilers give the right answer. */
 | |
| #   define MY_ALIGNOF(type)   offsetof(my_alignof_helper<type>, m2)
 | |
| # else
 | |
| #   define MY_ALIGNOF(type)   offsetof(struct { char m1; type m2; }, m2)
 | |
| # endif
 | |
| #endif
 | |
| 
 | |
| #ifndef MY_ASSERT_UNREACHABLE
 | |
| # define MY_ASSERT_UNREACHABLE()  do { assert(0); } while (0)
 | |
| #endif
 | |
| 
 | |
| /**
 | |
|   C++ Type Traits
 | |
| */
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| 
 | |
| /**
 | |
|   Opaque storage with a particular alignment.
 | |
| */
 | |
| # if defined(MY_ALIGNED)
 | |
| /* Partial specialization used due to MSVC++. */
 | |
| template<size_t alignment> struct my_alignment_imp;
 | |
| template<> struct MY_ALIGNED(1) my_alignment_imp<1> {};
 | |
| template<> struct MY_ALIGNED(2) my_alignment_imp<2> {};
 | |
| template<> struct MY_ALIGNED(4) my_alignment_imp<4> {};
 | |
| template<> struct MY_ALIGNED(8) my_alignment_imp<8> {};
 | |
| template<> struct MY_ALIGNED(16) my_alignment_imp<16> {};
 | |
| /* ... expand as necessary. */
 | |
| # else
 | |
| template<size_t alignment>
 | |
| struct my_alignment_imp { double m1; };
 | |
| # endif
 | |
| 
 | |
| /**
 | |
|   A POD type with a given size and alignment.
 | |
| 
 | |
|   @remark If the compiler does not support a alignment attribute
 | |
|           (MY_ALIGN macro), the default alignment of a double is
 | |
|           used instead.
 | |
| 
 | |
|   @tparam size        The minimum size.
 | |
|   @tparam alignment   The desired alignment: 1, 2, 4, 8 or 16.
 | |
| */
 | |
| template <size_t size, size_t alignment>
 | |
| struct my_aligned_storage
 | |
| {
 | |
|   union
 | |
|   {
 | |
|     char data[size];
 | |
|     my_alignment_imp<alignment> align;
 | |
|   };
 | |
| };
 | |
| 
 | |
| #endif /* __cplusplus */
 | |
| 
 | |
| #include <my_attribute.h>
 | |
| 
 | |
| #endif /* MY_COMPILER_INCLUDED */
 |