// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. // This source code is licensed under both the GPLv2 (found in the // COPYING file in the root directory) and Apache 2.0 License // (found in the LICENSE.Apache file in the root directory). #pragma once #include #include #include #include "rocksdb/rocksdb_namespace.h" namespace ROCKSDB_NAMESPACE { // The helper function to assert the move from dynamic_cast<> to // static_cast<> is correct. This function is to deal with legacy code. // It is not recommended to add new code to issue class casting. The preferred // solution is to implement the functionality without a need of casting. template inline DestClass* static_cast_with_check(SrcClass* x) { DestClass* ret = static_cast(x); #ifdef ROCKSDB_USE_RTTI assert(ret == dynamic_cast(x)); #endif return ret; } template inline std::shared_ptr static_cast_with_check( std::shared_ptr&& x) { #if defined(ROCKSDB_USE_RTTI) && !defined(NDEBUG) auto orig_raw = x.get(); #endif auto ret = std::static_pointer_cast(std::move(x)); #if defined(ROCKSDB_USE_RTTI) && !defined(NDEBUG) assert(ret.get() == dynamic_cast(orig_raw)); #endif return ret; } // A wrapper around static_cast for lossless conversion between integral // types, including enum types. For example, this can be used for converting // between signed/unsigned or enum type and underlying type without fear of // stripping away data, now or in the future. template inline To lossless_cast(From x) { using FromValue = typename std::remove_reference::type; static_assert( std::is_integral::value || std::is_enum::value, "Only works on integral types"); static_assert(std::is_integral::value || std::is_enum::value, "Only works on integral types"); static_assert(sizeof(To) >= sizeof(FromValue), "Must be lossless"); return static_cast(x); } // For disambiguating a potentially heterogeneous aggregate as a homogeneous // initializer list. E.g. might be able to write List({x, y}) in some cases // instead of std::vector({x, y}). template inline const std::initializer_list& List( const std::initializer_list& list) { return list; } // UnownedPtr is useful as an efficient "optional reference" that can't // be accidentally converted to std::shared_ptr nor std::unique_ptr. template class UnownedPtr { public: UnownedPtr() = default; UnownedPtr(std::nullptr_t) {} UnownedPtr(T* ptr) : ptr_(ptr) {} UnownedPtr(const UnownedPtr&) = default; UnownedPtr(UnownedPtr&&) = default; UnownedPtr& operator=(const UnownedPtr&) = default; UnownedPtr& operator=(UnownedPtr&&) = default; T* get() const { return ptr_; } T* operator->() const { return ptr_; } T& operator*() const { return *ptr_; } operator bool() const { return ptr_ != nullptr; } private: T* ptr_ = nullptr; }; } // namespace ROCKSDB_NAMESPACE