nuclear@0: /************************************************************************************ nuclear@0: nuclear@0: PublicHeader: OVR_Kernel.h nuclear@0: Filename : OVR_Nullptr.h nuclear@0: Content : Implements C++11 nullptr for the case that the compiler doesn't. nuclear@0: Created : June 19, 2014 nuclear@0: Notes : nuclear@0: nuclear@0: Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. nuclear@0: nuclear@0: Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); nuclear@0: you may not use the Oculus VR Rift SDK except in compliance with the License, nuclear@0: which is provided at the time of installation or download, or which nuclear@0: otherwise accompanies this software in either electronic or hard copy form. nuclear@0: nuclear@0: You may obtain a copy of the License at nuclear@0: nuclear@0: http://www.oculusvr.com/licenses/LICENSE-3.2 nuclear@0: nuclear@0: Unless required by applicable law or agreed to in writing, the Oculus VR SDK nuclear@0: distributed under the License is distributed on an "AS IS" BASIS, nuclear@0: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. nuclear@0: See the License for the specific language governing permissions and nuclear@0: limitations under the License. nuclear@0: nuclear@0: ************************************************************************************/ nuclear@0: nuclear@0: #ifndef OVR_Nullptr_h nuclear@0: #define OVR_Nullptr_h nuclear@0: nuclear@0: #pragma once nuclear@0: nuclear@0: #include "OVR_Types.h" nuclear@0: nuclear@0: nuclear@0: //----------------------------------------------------------------------------------- nuclear@0: // ***** OVR_HAVE_std_nullptr_t nuclear@0: // nuclear@0: // Identifies if includes std::nullptr_t. nuclear@0: // nuclear@0: #if !defined(OVR_HAVE_std_nullptr_t) && defined(OVR_CPP11_ENABLED) nuclear@0: #if defined(OVR_STDLIB_LIBCPP) nuclear@0: #define OVR_HAVE_std_nullptr_t 1 nuclear@0: #elif defined(OVR_STDLIB_LIBSTDCPP) nuclear@0: #if (__GLIBCXX__ >= 20110325) && (__GLIBCXX__ != 20110428) && (__GLIBCXX__ != 20120702) nuclear@0: #define OVR_HAVE_std_nullptr_t 1 nuclear@0: #endif nuclear@0: #elif defined(_MSC_VER) && (_MSC_VER >= 1600) // VS2010+ nuclear@0: #define OVR_HAVE_std_nullptr_t 1 nuclear@0: #elif defined(__clang__) nuclear@0: #define OVR_HAVE_std_nullptr_t 1 nuclear@0: #elif defined(OVR_CPP_GNUC) && (OVR_CC_VERSION >= 406) // GCC 4.6+ nuclear@0: #define OVR_HAVE_std_nullptr_t 1 nuclear@0: #endif nuclear@0: #endif nuclear@0: nuclear@0: nuclear@0: //----------------------------------------------------------------------------------- nuclear@0: // ***** nullptr / std::nullptr_t nuclear@0: // nuclear@0: // Declares and defines nullptr and related types. nuclear@0: // nuclear@0: #if defined(OVR_CPP_NO_NULLPTR) nuclear@0: namespace std nuclear@0: { nuclear@0: class nullptr_t nuclear@0: { nuclear@0: public: nuclear@0: template nuclear@0: operator T*() const nuclear@0: { return 0; } nuclear@0: nuclear@0: template nuclear@0: operator T C::*() const nuclear@0: { return 0; } nuclear@0: nuclear@0: #if OVR_CPP_NO_EXPLICIT_CONVERSION_OPERATORS nuclear@0: typedef void* (nullptr_t::*bool_)() const; // 4.12,p1. We can't portably use operator bool(){ return false; } because bool nuclear@0: operator bool_() const // is convertable to int which breaks other required functionality. nuclear@0: { return false; } nuclear@0: #else nuclear@0: operator bool() const nuclear@0: { return false; } nuclear@0: #endif nuclear@0: nuclear@0: private: nuclear@0: void operator&() const; // 5.2.10,p9 nuclear@0: }; nuclear@0: nuclear@0: inline nullptr_t nullptr_get() nuclear@0: { nuclear@0: nullptr_t n = { }; nuclear@0: return n; nuclear@0: } nuclear@0: nuclear@0: #if !defined(nullptr) nuclear@0: #define nullptr nullptr_get() nuclear@0: #endif nuclear@0: nuclear@0: } // namespace std nuclear@0: nuclear@0: nuclear@0: // 5.9,p2 p4 nuclear@0: // 13.6, p13 nuclear@0: template nuclear@0: inline bool operator==(T* pT, const std::nullptr_t) nuclear@0: { return pT == 0; } nuclear@0: nuclear@0: template nuclear@0: inline bool operator==(const std::nullptr_t, T* pT) nuclear@0: { return pT == 0; } nuclear@0: nuclear@0: template nuclear@0: inline bool operator==(const std::nullptr_t, T U::* pU) nuclear@0: { return pU == 0; } nuclear@0: nuclear@0: template nuclear@0: inline bool operator==(T U::* pTU, const std::nullptr_t) nuclear@0: { return pTU == 0; } nuclear@0: nuclear@0: inline bool operator==(const std::nullptr_t, const std::nullptr_t) nuclear@0: { return true; } nuclear@0: nuclear@0: inline bool operator!=(const std::nullptr_t, const std::nullptr_t) nuclear@0: { return false; } nuclear@0: nuclear@0: inline bool operator<(const std::nullptr_t, const std::nullptr_t) nuclear@0: { return false; } nuclear@0: nuclear@0: inline bool operator<=(const std::nullptr_t, const std::nullptr_t) nuclear@0: { return true; } nuclear@0: nuclear@0: inline bool operator>(const std::nullptr_t, const std::nullptr_t) nuclear@0: { return false; } nuclear@0: nuclear@0: inline bool operator>=(const std::nullptr_t, const std::nullptr_t) nuclear@0: { return true; } nuclear@0: nuclear@0: using std::nullptr_t; nuclear@0: using std::nullptr_get; nuclear@0: nuclear@0: // Some compilers natively support C++11 nullptr but the standard library being used nuclear@0: // doesn't declare std::nullptr_t, in which case we provide one ourselves. nuclear@0: #elif !defined(OVR_HAVE_std_nullptr_t) && !defined(OVR_CPP_NO_DECLTYPE) nuclear@0: namespace std { typedef decltype(nullptr) nullptr_t; } nuclear@0: #endif nuclear@0: nuclear@0: nuclear@0: #endif nuclear@0: