Coverage Report

Created: 2026-05-31 07:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rocksdb/util/cast_util.h
Line
Count
Source
1
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2
//  This source code is licensed under both the GPLv2 (found in the
3
//  COPYING file in the root directory) and Apache 2.0 License
4
//  (found in the LICENSE.Apache file in the root directory).
5
6
#pragma once
7
8
#include <initializer_list>
9
#include <memory>
10
#include <type_traits>
11
12
#include "rocksdb/rocksdb_namespace.h"
13
14
namespace ROCKSDB_NAMESPACE {
15
// The helper function to assert the move from dynamic_cast<> to
16
// static_cast<> is correct. This function is to deal with legacy code.
17
// It is not recommended to add new code to issue class casting. The preferred
18
// solution is to implement the functionality without a need of casting.
19
template <class DestClass, class SrcClass>
20
2.72M
inline DestClass* static_cast_with_check(SrcClass* x) {
21
2.72M
  DestClass* ret = static_cast<DestClass*>(x);
22
#ifdef ROCKSDB_USE_RTTI
23
  assert(ret == dynamic_cast<DestClass*>(x));
24
#endif
25
2.72M
  return ret;
26
2.72M
}
Unexecuted instantiation: rocksdb::ColumnFamilyHandleImpl* rocksdb::static_cast_with_check<rocksdb::ColumnFamilyHandleImpl, rocksdb::ColumnFamilyHandleImpl>(rocksdb::ColumnFamilyHandleImpl*)
rocksdb::ColumnFamilyHandleImpl* rocksdb::static_cast_with_check<rocksdb::ColumnFamilyHandleImpl, rocksdb::ColumnFamilyHandle>(rocksdb::ColumnFamilyHandle*)
Line
Count
Source
20
1.58M
inline DestClass* static_cast_with_check(SrcClass* x) {
21
1.58M
  DestClass* ret = static_cast<DestClass*>(x);
22
#ifdef ROCKSDB_USE_RTTI
23
  assert(ret == dynamic_cast<DestClass*>(x));
24
#endif
25
1.58M
  return ret;
26
1.58M
}
Unexecuted instantiation: rocksdb::SnapshotImpl const* rocksdb::static_cast_with_check<rocksdb::SnapshotImpl const, rocksdb::Snapshot const>(rocksdb::Snapshot const*)
rocksdb::SstFileManagerImpl* rocksdb::static_cast_with_check<rocksdb::SstFileManagerImpl, rocksdb::SstFileManager>(rocksdb::SstFileManager*)
Line
Count
Source
20
130k
inline DestClass* static_cast_with_check(SrcClass* x) {
21
130k
  DestClass* ret = static_cast<DestClass*>(x);
22
#ifdef ROCKSDB_USE_RTTI
23
  assert(ret == dynamic_cast<DestClass*>(x));
24
#endif
25
130k
  return ret;
26
130k
}
Unexecuted instantiation: rocksdb::LRUCacheOptions* rocksdb::static_cast_with_check<rocksdb::LRUCacheOptions, rocksdb::ShardedCacheOptions>(rocksdb::ShardedCacheOptions*)
Unexecuted instantiation: rocksdb::HyperClockCacheOptions* rocksdb::static_cast_with_check<rocksdb::HyperClockCacheOptions, rocksdb::ShardedCacheOptions>(rocksdb::ShardedCacheOptions*)
rocksdb::DBImpl* rocksdb::static_cast_with_check<rocksdb::DBImpl, rocksdb::DB>(rocksdb::DB*)
Line
Count
Source
20
1.00M
inline DestClass* static_cast_with_check(SrcClass* x) {
21
1.00M
  DestClass* ret = static_cast<DestClass*>(x);
22
#ifdef ROCKSDB_USE_RTTI
23
  assert(ret == dynamic_cast<DestClass*>(x));
24
#endif
25
1.00M
  return ret;
26
1.00M
}
rocksdb::DBImpl* rocksdb::static_cast_with_check<rocksdb::DBImpl, rocksdb::DBImpl>(rocksdb::DBImpl*)
Line
Count
Source
20
10.5k
inline DestClass* static_cast_with_check(SrcClass* x) {
21
10.5k
  DestClass* ret = static_cast<DestClass*>(x);
22
#ifdef ROCKSDB_USE_RTTI
23
  assert(ret == dynamic_cast<DestClass*>(x));
24
#endif
25
10.5k
  return ret;
26
10.5k
}
Unexecuted instantiation: rocksdb::VersionSet::LogReporter* rocksdb::static_cast_with_check<rocksdb::VersionSet::LogReporter, rocksdb::log::Reader::Reporter>(rocksdb::log::Reader::Reporter*)
Unexecuted instantiation: rocksdb::WalFileImpl* rocksdb::static_cast_with_check<rocksdb::WalFileImpl, rocksdb::WalFile>(rocksdb::WalFile*)
Unexecuted instantiation: mock_env.cc:rocksdb::(anonymous namespace)::MockEnvFileLock* rocksdb::static_cast_with_check<rocksdb::(anonymous namespace)::MockEnvFileLock, rocksdb::FileLock>(rocksdb::FileLock*)
Unexecuted instantiation: rocksdb::MockFileSystem* rocksdb::static_cast_with_check<rocksdb::MockFileSystem, rocksdb::FileSystem>(rocksdb::FileSystem*)
Unexecuted instantiation: rocksdb::HistogramImpl const* rocksdb::static_cast_with_check<rocksdb::HistogramImpl const, rocksdb::Histogram const>(rocksdb::Histogram const*)
Unexecuted instantiation: rocksdb::PessimisticTransaction* rocksdb::static_cast_with_check<rocksdb::PessimisticTransaction, rocksdb::Transaction>(rocksdb::Transaction*)
Unexecuted instantiation: rocksdb::PessimisticTransactionDB* rocksdb::static_cast_with_check<rocksdb::PessimisticTransactionDB, rocksdb::TransactionDB>(rocksdb::TransactionDB*)
Unexecuted instantiation: rocksdb::WriteUnpreparedTxn* rocksdb::static_cast_with_check<rocksdb::WriteUnpreparedTxn, rocksdb::Transaction>(rocksdb::Transaction*)
Unexecuted instantiation: rocksdb::WBWIIteratorImpl* rocksdb::static_cast_with_check<rocksdb::WBWIIteratorImpl, rocksdb::WBWIIterator>(rocksdb::WBWIIterator*)
27
28
template <class DestClass, class SrcClass>
29
inline std::shared_ptr<DestClass> static_cast_with_check(
30
    std::shared_ptr<SrcClass>&& x) {
31
#if defined(ROCKSDB_USE_RTTI) && !defined(NDEBUG)
32
  auto orig_raw = x.get();
33
#endif
34
  auto ret = std::static_pointer_cast<DestClass>(std::move(x));
35
#if defined(ROCKSDB_USE_RTTI) && !defined(NDEBUG)
36
  assert(ret.get() == dynamic_cast<DestClass*>(orig_raw));
37
#endif
38
  return ret;
39
}
40
41
// A wrapper around static_cast for lossless conversion between integral
42
// types, including enum types, and pointers to such types. For example, this
43
// can be used for converting between signed/unsigned or enum type and
44
// underlying type without fear of stripping away data, now or in the future.
45
template <typename To, typename From>
46
25.2M
inline To lossless_cast(From x) {
47
25.2M
  using FromValue = typename std::remove_reference_t<From>;
48
25.2M
  if constexpr (std::is_pointer_v<FromValue>) {
49
24.4M
    static_assert(std::is_pointer_v<To>);
50
24.4M
    using FromDeref = typename std::remove_pointer_t<FromValue>;
51
24.4M
    using ToDeref = typename std::remove_pointer_t<To>;
52
24.4M
    static_assert(std::is_integral_v<FromDeref> || std::is_enum_v<FromDeref>,
53
24.4M
                  "Only works on integral types");
54
24.4M
    static_assert(std::is_integral_v<ToDeref> || std::is_enum_v<To>,
55
24.4M
                  "Only works on integral types");
56
24.4M
    static_assert(sizeof(ToDeref) == sizeof(FromDeref), "Must be lossless");
57
24.4M
    return reinterpret_cast<To>(x);
58
24.4M
  } else {
59
715k
    static_assert(std::is_integral_v<FromValue> || std::is_enum_v<FromValue>,
60
715k
                  "Only works on integral types");
61
715k
    static_assert(std::is_integral_v<To> || std::is_enum_v<To>,
62
715k
                  "Only works on integral types");
63
715k
    static_assert(sizeof(To) >= sizeof(FromValue), "Must be lossless");
64
715k
    return static_cast<To>(x);
65
715k
  }
66
25.2M
}
unsigned char const* rocksdb::lossless_cast<unsigned char const*, char const*>(char const*)
Line
Count
Source
46
18.9M
inline To lossless_cast(From x) {
47
18.9M
  using FromValue = typename std::remove_reference_t<From>;
48
18.9M
  if constexpr (std::is_pointer_v<FromValue>) {
49
18.9M
    static_assert(std::is_pointer_v<To>);
50
18.9M
    using FromDeref = typename std::remove_pointer_t<FromValue>;
51
18.9M
    using ToDeref = typename std::remove_pointer_t<To>;
52
18.9M
    static_assert(std::is_integral_v<FromDeref> || std::is_enum_v<FromDeref>,
53
18.9M
                  "Only works on integral types");
54
18.9M
    static_assert(std::is_integral_v<ToDeref> || std::is_enum_v<To>,
55
18.9M
                  "Only works on integral types");
56
18.9M
    static_assert(sizeof(ToDeref) == sizeof(FromDeref), "Must be lossless");
57
18.9M
    return reinterpret_cast<To>(x);
58
  } else {
59
    static_assert(std::is_integral_v<FromValue> || std::is_enum_v<FromValue>,
60
                  "Only works on integral types");
61
    static_assert(std::is_integral_v<To> || std::is_enum_v<To>,
62
                  "Only works on integral types");
63
    static_assert(sizeof(To) >= sizeof(FromValue), "Must be lossless");
64
    return static_cast<To>(x);
65
  }
66
18.9M
}
unsigned char* rocksdb::lossless_cast<unsigned char*, char*>(char*)
Line
Count
Source
46
2.79M
inline To lossless_cast(From x) {
47
2.79M
  using FromValue = typename std::remove_reference_t<From>;
48
2.79M
  if constexpr (std::is_pointer_v<FromValue>) {
49
2.79M
    static_assert(std::is_pointer_v<To>);
50
2.79M
    using FromDeref = typename std::remove_pointer_t<FromValue>;
51
2.79M
    using ToDeref = typename std::remove_pointer_t<To>;
52
2.79M
    static_assert(std::is_integral_v<FromDeref> || std::is_enum_v<FromDeref>,
53
2.79M
                  "Only works on integral types");
54
2.79M
    static_assert(std::is_integral_v<ToDeref> || std::is_enum_v<To>,
55
2.79M
                  "Only works on integral types");
56
2.79M
    static_assert(sizeof(ToDeref) == sizeof(FromDeref), "Must be lossless");
57
2.79M
    return reinterpret_cast<To>(x);
58
  } else {
59
    static_assert(std::is_integral_v<FromValue> || std::is_enum_v<FromValue>,
60
                  "Only works on integral types");
61
    static_assert(std::is_integral_v<To> || std::is_enum_v<To>,
62
                  "Only works on integral types");
63
    static_assert(sizeof(To) >= sizeof(FromValue), "Must be lossless");
64
    return static_cast<To>(x);
65
  }
66
2.79M
}
char* rocksdb::lossless_cast<char*, unsigned char*>(unsigned char*)
Line
Count
Source
46
2.79M
inline To lossless_cast(From x) {
47
2.79M
  using FromValue = typename std::remove_reference_t<From>;
48
2.79M
  if constexpr (std::is_pointer_v<FromValue>) {
49
2.79M
    static_assert(std::is_pointer_v<To>);
50
2.79M
    using FromDeref = typename std::remove_pointer_t<FromValue>;
51
2.79M
    using ToDeref = typename std::remove_pointer_t<To>;
52
2.79M
    static_assert(std::is_integral_v<FromDeref> || std::is_enum_v<FromDeref>,
53
2.79M
                  "Only works on integral types");
54
2.79M
    static_assert(std::is_integral_v<ToDeref> || std::is_enum_v<To>,
55
2.79M
                  "Only works on integral types");
56
2.79M
    static_assert(sizeof(ToDeref) == sizeof(FromDeref), "Must be lossless");
57
2.79M
    return reinterpret_cast<To>(x);
58
  } else {
59
    static_assert(std::is_integral_v<FromValue> || std::is_enum_v<FromValue>,
60
                  "Only works on integral types");
61
    static_assert(std::is_integral_v<To> || std::is_enum_v<To>,
62
                  "Only works on integral types");
63
    static_assert(sizeof(To) >= sizeof(FromValue), "Must be lossless");
64
    return static_cast<To>(x);
65
  }
66
2.79M
}
Unexecuted instantiation: rocksdb::CacheTier rocksdb::lossless_cast<rocksdb::CacheTier, char>(char)
Unexecuted instantiation: rocksdb::CompressionType rocksdb::lossless_cast<rocksdb::CompressionType, char>(char)
Unexecuted instantiation: char rocksdb::lossless_cast<char, rocksdb::CacheTier>(rocksdb::CacheTier)
Unexecuted instantiation: char rocksdb::lossless_cast<char, rocksdb::CompressionType>(rocksdb::CompressionType)
rocksdb::ChecksumType rocksdb::lossless_cast<rocksdb::ChecksumType, char>(char)
Line
Count
Source
46
115k
inline To lossless_cast(From x) {
47
115k
  using FromValue = typename std::remove_reference_t<From>;
48
  if constexpr (std::is_pointer_v<FromValue>) {
49
    static_assert(std::is_pointer_v<To>);
50
    using FromDeref = typename std::remove_pointer_t<FromValue>;
51
    using ToDeref = typename std::remove_pointer_t<To>;
52
    static_assert(std::is_integral_v<FromDeref> || std::is_enum_v<FromDeref>,
53
                  "Only works on integral types");
54
    static_assert(std::is_integral_v<ToDeref> || std::is_enum_v<To>,
55
                  "Only works on integral types");
56
    static_assert(sizeof(ToDeref) == sizeof(FromDeref), "Must be lossless");
57
    return reinterpret_cast<To>(x);
58
115k
  } else {
59
115k
    static_assert(std::is_integral_v<FromValue> || std::is_enum_v<FromValue>,
60
115k
                  "Only works on integral types");
61
115k
    static_assert(std::is_integral_v<To> || std::is_enum_v<To>,
62
115k
                  "Only works on integral types");
63
115k
    static_assert(sizeof(To) >= sizeof(FromValue), "Must be lossless");
64
115k
    return static_cast<To>(x);
65
115k
  }
66
115k
}
unsigned char rocksdb::lossless_cast<unsigned char, char>(char)
Line
Count
Source
46
600k
inline To lossless_cast(From x) {
47
600k
  using FromValue = typename std::remove_reference_t<From>;
48
  if constexpr (std::is_pointer_v<FromValue>) {
49
    static_assert(std::is_pointer_v<To>);
50
    using FromDeref = typename std::remove_pointer_t<FromValue>;
51
    using ToDeref = typename std::remove_pointer_t<To>;
52
    static_assert(std::is_integral_v<FromDeref> || std::is_enum_v<FromDeref>,
53
                  "Only works on integral types");
54
    static_assert(std::is_integral_v<ToDeref> || std::is_enum_v<To>,
55
                  "Only works on integral types");
56
    static_assert(sizeof(ToDeref) == sizeof(FromDeref), "Must be lossless");
57
    return reinterpret_cast<To>(x);
58
600k
  } else {
59
600k
    static_assert(std::is_integral_v<FromValue> || std::is_enum_v<FromValue>,
60
600k
                  "Only works on integral types");
61
600k
    static_assert(std::is_integral_v<To> || std::is_enum_v<To>,
62
600k
                  "Only works on integral types");
63
600k
    static_assert(sizeof(To) >= sizeof(FromValue), "Must be lossless");
64
600k
    return static_cast<To>(x);
65
600k
  }
66
600k
}
Unexecuted instantiation: unsigned char rocksdb::lossless_cast<unsigned char, rocksdb::CompressionType>(rocksdb::CompressionType)
67
68
// For disambiguating a potentially heterogeneous aggregate as a homogeneous
69
// initializer list. E.g. might be able to write List({x, y}) in some cases
70
// instead of std::vector<const Widget&>({x, y}).
71
template <typename T>
72
inline const std::initializer_list<T>& List(
73
    const std::initializer_list<T>& list) {
74
  return list;
75
}
76
77
// UnownedPtr<T> is useful as an efficient "optional reference" that can't
78
// be accidentally converted to std::shared_ptr<T> nor std::unique_ptr<T>.
79
template <typename T>
80
class UnownedPtr {
81
 public:
82
43.4k
  UnownedPtr() = default;
83
251k
  UnownedPtr(std::nullptr_t) {}
rocksdb::UnownedPtr<rocksdb::SeqnoToTimeMapping const>::UnownedPtr(decltype(nullptr))
Line
Count
Source
83
48.1k
  UnownedPtr(std::nullptr_t) {}
rocksdb::UnownedPtr<rocksdb::Compressor>::UnownedPtr(decltype(nullptr))
Line
Count
Source
83
87.7k
  UnownedPtr(std::nullptr_t) {}
rocksdb::UnownedPtr<rocksdb::Decompressor>::UnownedPtr(decltype(nullptr))
Line
Count
Source
83
115k
  UnownedPtr(std::nullptr_t) {}
84
552k
  UnownedPtr(T* ptr) : ptr_(ptr) {}
rocksdb::UnownedPtr<rocksdb::SeqnoToTimeMapping const>::UnownedPtr(rocksdb::SeqnoToTimeMapping const*)
Line
Count
Source
84
33.8k
  UnownedPtr(T* ptr) : ptr_(ptr) {}
rocksdb::UnownedPtr<rocksdb::CompressionManager>::UnownedPtr(rocksdb::CompressionManager*)
Line
Count
Source
84
224k
  UnownedPtr(T* ptr) : ptr_(ptr) {}
Unexecuted instantiation: rocksdb::UnownedPtr<rocksdb::Compressor>::UnownedPtr(rocksdb::Compressor*)
rocksdb::UnownedPtr<rocksdb::Decompressor>::UnownedPtr(rocksdb::Decompressor*)
Line
Count
Source
84
283k
  UnownedPtr(T* ptr) : ptr_(ptr) {}
rocksdb::UnownedPtr<rocksdb::TruncatedRangeDelIterator>::UnownedPtr(rocksdb::TruncatedRangeDelIterator*)
Line
Count
Source
84
10.9k
  UnownedPtr(T* ptr) : ptr_(ptr) {}
85
  UnownedPtr(const UnownedPtr&) = default;
86
  UnownedPtr(UnownedPtr&&) = default;
87
  UnownedPtr& operator=(const UnownedPtr&) = default;
88
  UnownedPtr& operator=(UnownedPtr&&) = default;
89
90
141k
  T* get() const { return ptr_; }
rocksdb::UnownedPtr<rocksdb::Decompressor>::get() const
Line
Count
Source
90
97.6k
  T* get() const { return ptr_; }
rocksdb::UnownedPtr<rocksdb::Compressor>::get() const
Line
Count
Source
90
43.4k
  T* get() const { return ptr_; }
91
0
  T* operator->() const { return ptr_; }
Unexecuted instantiation: rocksdb::UnownedPtr<rocksdb::CompressionManager>::operator->() const
Unexecuted instantiation: rocksdb::UnownedPtr<rocksdb::SeqnoToTimeMapping const>::operator->() const
Unexecuted instantiation: rocksdb::UnownedPtr<rocksdb::Compressor>::operator->() const
Unexecuted instantiation: rocksdb::UnownedPtr<rocksdb::Decompressor>::operator->() const
Unexecuted instantiation: rocksdb::UnownedPtr<rocksdb::TruncatedRangeDelIterator>::operator->() const
92
0
  T& operator*() const { return *ptr_; }
Unexecuted instantiation: rocksdb::UnownedPtr<rocksdb::SeqnoToTimeMapping const>::operator*() const
Unexecuted instantiation: rocksdb::UnownedPtr<rocksdb::Decompressor>::operator*() const
93
324k
  operator bool() const { return ptr_ != nullptr; }
rocksdb::UnownedPtr<rocksdb::CompressionManager>::operator bool() const
Line
Count
Source
93
202k
  operator bool() const { return ptr_ != nullptr; }
rocksdb::UnownedPtr<rocksdb::SeqnoToTimeMapping const>::operator bool() const
Line
Count
Source
93
24.6k
  operator bool() const { return ptr_ != nullptr; }
rocksdb::UnownedPtr<rocksdb::Compressor>::operator bool() const
Line
Count
Source
93
86.3k
  operator bool() const { return ptr_ != nullptr; }
Unexecuted instantiation: rocksdb::UnownedPtr<rocksdb::Decompressor>::operator bool() const
rocksdb::UnownedPtr<rocksdb::TruncatedRangeDelIterator>::operator bool() const
Line
Count
Source
93
10.9k
  operator bool() const { return ptr_ != nullptr; }
94
95
 private:
96
  T* ptr_ = nullptr;
97
};
98
99
}  // namespace ROCKSDB_NAMESPACE