nullguard.h 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // Copyright 2022 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. //
  15. // -----------------------------------------------------------------------------
  16. // File: log/internal/nullguard.h
  17. // -----------------------------------------------------------------------------
  18. //
  19. // NullGuard exists such that NullGuard<T>::Guard(v) returns v, unless passed a
  20. // nullptr_t, or a null char* or const char*, in which case it returns "(null)".
  21. // This allows streaming NullGuard<T>::Guard(v) to an output stream without
  22. // hitting undefined behavior for null values.
  23. #ifndef ABSL_LOG_INTERNAL_NULLGUARD_H_
  24. #define ABSL_LOG_INTERNAL_NULLGUARD_H_
  25. #include <array>
  26. #include <cstddef>
  27. #include "absl/base/attributes.h"
  28. #include "absl/base/config.h"
  29. namespace absl {
  30. ABSL_NAMESPACE_BEGIN
  31. namespace log_internal {
  32. ABSL_CONST_INIT ABSL_DLL extern const std::array<char, 7> kCharNull;
  33. ABSL_CONST_INIT ABSL_DLL extern const std::array<signed char, 7>
  34. kSignedCharNull;
  35. ABSL_CONST_INIT ABSL_DLL extern const std::array<unsigned char, 7>
  36. kUnsignedCharNull;
  37. template <typename T>
  38. struct NullGuard final {
  39. static const T& Guard(const T& v) { return v; }
  40. };
  41. template <>
  42. struct NullGuard<char*> final {
  43. static const char* Guard(const char* v) { return v ? v : kCharNull.data(); }
  44. };
  45. template <>
  46. struct NullGuard<const char*> final {
  47. static const char* Guard(const char* v) { return v ? v : kCharNull.data(); }
  48. };
  49. template <>
  50. struct NullGuard<signed char*> final {
  51. static const signed char* Guard(const signed char* v) {
  52. return v ? v : kSignedCharNull.data();
  53. }
  54. };
  55. template <>
  56. struct NullGuard<const signed char*> final {
  57. static const signed char* Guard(const signed char* v) {
  58. return v ? v : kSignedCharNull.data();
  59. }
  60. };
  61. template <>
  62. struct NullGuard<unsigned char*> final {
  63. static const unsigned char* Guard(const unsigned char* v) {
  64. return v ? v : kUnsignedCharNull.data();
  65. }
  66. };
  67. template <>
  68. struct NullGuard<const unsigned char*> final {
  69. static const unsigned char* Guard(const unsigned char* v) {
  70. return v ? v : kUnsignedCharNull.data();
  71. }
  72. };
  73. template <>
  74. struct NullGuard<std::nullptr_t> final {
  75. static const char* Guard(const std::nullptr_t&) { return kCharNull.data(); }
  76. };
  77. } // namespace log_internal
  78. ABSL_NAMESPACE_END
  79. } // namespace absl
  80. #endif // ABSL_LOG_INTERNAL_NULLGUARD_H_