chromium/chrome/updater/enum_traits.h

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_UPDATER_ENUM_TRAITS_H_
#define CHROME_UPDATER_ENUM_TRAITS_H_

#include <concepts>
#include <optional>
#include <ostream>
#include <type_traits>

#include "base/types/cxx23_to_underlying.h"

namespace updater {

// Provides a way to safely convert numeric types to enumerated values. To use
// this facility, the enum definition must be annotated with traits to specify
// the range of the enum values. Due to how specialization of class templates
// works in C++14, the `EnumTraits` specialization of the primary template must
// be defined inside the `updater` namespace, where the primary template is
// defined. Traits for enum types defined inside other scopes, such as nested
// classes or other namespaces, may not work.
//
// enum class MyEnum {
//   kVal1 = -1,
//   kVal2 = 0,
//   kVal3 = 1,
// };
//
// template <>
// struct EnumTraits<MyEnum> {
//   static constexpr MyEnum first_elem = MyEnum::kVal1;
//   static constexpr MyEnum last_elem = MyEnum::kVal3;
// };
//
// MyEnum val = *CheckedCastToEnum<MyEnum>(-1);

template <typename T>
  requires(std::is_enum_v<T>)
struct EnumTraits {};

// Returns an optional value of an enum type T if the conversion from an
// integer value `v` is safe, meaning that `v` is within the bounds of the enum.
// The enum type must be annotated with traits to specify the lower and upper
// bounds of the enum values.
template <typename T>
  requires(std::is_enum_v<T>)
constexpr std::optional<T> CheckedCastToEnum(std::underlying_type_t<T> v) {}

}  // namespace updater

#endif  // CHROME_UPDATER_ENUM_TRAITS_H_