76 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			76 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | // Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal. | ||
|  | // Copyright (C) 2016 Andrzej Krzemienski. | ||
|  | // | ||
|  | // Use, modification, and distribution is subject to the Boost Software | ||
|  | // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | ||
|  | // http://www.boost.org/LICENSE_1_0.txt) | ||
|  | // | ||
|  | // See http://www.boost.org/libs/optional for documentation. | ||
|  | // | ||
|  | // You are welcome to contact the author at: | ||
|  | //  fernando_cacciola@hotmail.com | ||
|  | //  akrzemi1@gmail.com | ||
|  | 
 | ||
|  | #ifndef BOOST_OPTIONAL_OPTIONAL_DETAIL_OPTIONAL_ALIGNED_STORAGE_AJK_12FEB2016_HPP | ||
|  | #define BOOST_OPTIONAL_OPTIONAL_DETAIL_OPTIONAL_ALIGNED_STORAGE_AJK_12FEB2016_HPP | ||
|  | 
 | ||
|  | namespace boost { | ||
|  | 
 | ||
|  | namespace optional_detail { | ||
|  | // This local class is used instead of that in "aligned_storage.hpp" | ||
|  | // because I've found the 'official' class to ICE BCB5.5 | ||
|  | // when some types are used with optional<> | ||
|  | // (due to sizeof() passed down as a non-type template parameter) | ||
|  | template <class T> | ||
|  | class aligned_storage | ||
|  | { | ||
|  |     // Borland ICEs if unnamed unions are used for this! | ||
|  |     union | ||
|  |     // This works around GCC warnings about breaking strict aliasing rules when casting storage address to T* | ||
|  | #if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS) | ||
|  |     __attribute__((__may_alias__)) | ||
|  | #endif | ||
|  |     dummy_u | ||
|  |     { | ||
|  |         char data[ sizeof(T) ]; | ||
|  |         BOOST_DEDUCED_TYPENAME type_with_alignment< | ||
|  |           ::boost::alignment_of<T>::value >::type aligner_; | ||
|  |     } dummy_ ; | ||
|  | 
 | ||
|  |   public: | ||
|  | 
 | ||
|  | #if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS) | ||
|  |     void const* address() const { return &dummy_; } | ||
|  |     void      * address()       { return &dummy_; } | ||
|  | #else | ||
|  |     void const* address() const { return dummy_.data; } | ||
|  |     void      * address()       { return dummy_.data; } | ||
|  | #endif | ||
|  | 
 | ||
|  | #if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS) | ||
|  | 	// This workaround is supposed to silence GCC warnings about broken strict aliasing rules | ||
|  | 	T const* ptr_ref() const | ||
|  | 	{ | ||
|  | 		union { void const* ap_pvoid; T const* as_ptype; } caster = { address() }; | ||
|  | 		return caster.as_ptype; | ||
|  | 	} | ||
|  | 	T *      ptr_ref() | ||
|  | 	{ | ||
|  | 		union { void* ap_pvoid; T* as_ptype; } caster = { address() }; | ||
|  | 		return caster.as_ptype; | ||
|  | 	} | ||
|  | #else | ||
|  | 	T const* ptr_ref() const { return static_cast<T const*>(address()); } | ||
|  | 	T *      ptr_ref()       { return static_cast<T *>     (address()); } | ||
|  | #endif | ||
|  | 
 | ||
|  | 	T const& ref() const { return *ptr_ref(); } | ||
|  | 	T &      ref()       { return *ptr_ref(); } | ||
|  |    | ||
|  | } ; | ||
|  | 
 | ||
|  | } // namespace optional_detail | ||
|  | } // namespace boost | ||
|  | 
 | ||
|  | #endif // header guard |