include/native/dxapi/dxcommon.h (104 lines of code) (raw):

/* * Copyright 2021 EPAM Systems, Inc * * See the NOTICE file distributed with this work for additional information * regarding copyright ownership. Licensed under the Apache License, * Version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ #pragma once #include "dxplatform.h" #include <stdexcept> // "Disallow evil constructors" macros #define DISALLOW_COPY_AND_ASSIGN(TypeName) private: \ TypeName(const TypeName&) = delete; \ void operator=(const TypeName&) = delete #define DISALLOW_DEFAULT_CONSTRUCTORS(TypeName) private: \ TypeName() = delete; \ TypeName(const TypeName&) = delete; \ void operator=(const TypeName&) = delete namespace DxApi { template<typename T> class Nullable { public: INLINE Nullable() : value_(), isSet_(false) {} INLINE Nullable(T value) : value_(value), isSet_(true) {} INLINE Nullable(const Nullable& other) : value_(other.value_), isSet_(other.isSet_) {} INLINE friend void swap(Nullable& a, Nullable& b) { using std::swap; swap(a.value_, b.value_); swap(a.isSet_, b.isSet_); } INLINE const Nullable<T>& operator=(const Nullable<T> &other) { return set(other.value_, other.isSet_); } INLINE const Nullable<T>& operator=(const T &value) { return set(value, true); } INLINE const Nullable<T>& operator=(std::nullptr_t other) { return set(T(), false); } INLINE bool operator==(const T &value) const { return isSet_ && value_ == value; } INLINE bool operator==(const Nullable<T>& other) const { return isSet_ == other.isSet_ && (!isSet_ || value_ == other.value_); } INLINE const T& get() const { if (isSet_) return value_; else throw std::logic_error("Attempting to get value of empty Nullable"); } INLINE T& get() { if (isSet_) return value_; else throw std::logic_error("Attempting to get value of empty Nullable"); } INLINE bool is_set() const { return isSet_; } INLINE bool has_value() const { return isSet_; } INLINE bool is_null() const { return !isSet_; } INLINE void reset() { set(T(), false); } private: INLINE const Nullable<T>& set(const T &value, bool isSet = true) { value_ = value; isSet_ = isSet; return *this; } private: T value_; bool isSet_; }; } namespace DxApiImpl { //// This template is used for DxApi constant enumeration types template<typename INTTYPE, class ENUM> class EnumClass : public ENUM { public: // Return underlying integer type INLINE INTTYPE toInt() const { return value_; } // Convert to enum type INLINE operator typename EnumClass::Enum() const { return (typename EnumClass::Enum)value_; } // Convert to constant string //const char * toString() const; /*INLINE friend std::ostream& operator<<(std::ostream& os, const EnumClass &me) { os << me.toString(); return os; }*/ // Convert to single char representation. Internal use char toChar() const; // Convert from integer. Will throw generic exception if out of range //INLINE static EnumClass from(INTTYPE x) { return (typename EnumClass::Enum)x; } // Convert from integer. Will throw generic exception if out of range //INLINE static EnumClass fromInt(int x) { return (typename EnumClass::Enum)x; } // Convert from string. Should match the enum name, case-sensitive. Will throw generic exception if out of range. //INLINE static EnumClass fromString(const char x[]) { return EnumClass(x); } // Convert from string. Should match the enum name, case-sensitive. Will throw generic exception if out of range //INLINE static EnumClass fromString(const std::string &x) { return EnumClass(x.c_str()); } // Convert from single-character representation. Internal use //static EnumClass fromChar(int x); // Copy constructor INLINE EnumClass(const EnumClass &other) : value_(other.value_) {} // Create from enum member //INLINE EnumClass(typename ENUM::Enum other) : value_(other) {} INLINE EnumClass(typename EnumClass::Enum other) : value_(other) {} // Create from string, same behavior as fromString //EnumClass(const char value[]); protected: // Default constructor is disabled, because there is no predefined default value for this template class EnumClass() = delete; // Holds actual value INTTYPE value_; }; // /** * This macro lets you declare DxApi enum class while being outside of DxApiImpl namespace * NOTE: For Linux port this implementation had to be made due to C++ standard rules(ignored by MSVC) preventing the previous one from working. * Basically, all non-trivial methods are redefined in this macro. Will be replaced with better solution, when/if it is found. */ #define ENUM_CLASS(INTTYPE, ENUM) \ class ENUM : public DxApiImpl::EnumClass<INTTYPE, ENUM##Enum> { \ public: \ char toChar() const; \ const char* toString() const; \ INLINE friend std::ostream& operator<<(std::ostream& os, const ENUM &me) \ { \ os << std::string(me.toString()); /* TODO: temp fix for clang linux compiler */ \ return os; \ } \ \ static ENUM fromChar(int x); \ INLINE static ENUM fromString(const char x[]) { return ENUM(x); } \ INLINE static ENUM fromString(const std::string &x) { return ENUM(x.c_str()); } \ INLINE static ENUM from(INTTYPE x) { return (ENUM::Enum)x; } \ INLINE static ENUM fromInt(int x) { return (ENUM::Enum)x; } \ ENUM(const char value[]); \ INLINE ENUM(const DxApiImpl::EnumClass<INTTYPE, ENUM##Enum> &o) : DxApiImpl::EnumClass<INTTYPE, ENUM##Enum>(o) {} \ INLINE ENUM(const DxApiImpl::EnumClass<INTTYPE, ENUM##Enum>::Enum o) : DxApiImpl::EnumClass<INTTYPE, ENUM##Enum>(o) {} \ }; // TODO: Cleanup //const { return EnumClass<T##Enum>::toString(); } /*namespace __dummy##__LINE__ { ::DxApiImpl::EnumClass<T##Enum> _dummy(0); }*/ // extern template class ::DxApiImpl::EnumClass<T##Enum>; #if 0 #define ENUM_CLASS(T) \ class T : public DxApiImpl::EnumClass<T##Enum> {} #endif }