// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COBALT_SRC_LIB_UTIL_NAMED_TYPE_H_
#define COBALT_SRC_LIB_UTIL_NAMED_TYPE_H_

#include <type_traits>
#include <utility>

namespace cobalt::util {

template <typename T>
using IsNotReference = typename std::enable_if<!std::is_reference<T>::value, void>::type;

// NamedType is used to wrap types (such as uint32_t) to allow them to be
// disambiguated from other instances of the same type.
//
// Note: this class is based on the idea discussed in
// https://www.fluentcpp.com/2017/05/05/news-strong-types-are-free
//
// Example:
//   void do_something(int height, int width);
//
//   int height = 10;
//   int width = 10;
//   do_something(width, height); // Wrong order, but it still compiles!
//
//   using Height = NamedType<int, struct HeightTag>;
//   using Width = NamedType<int, struct WidthTag>;
//   void do_something(Height height, Width width);
//
//   Height height(10);
//   Width width(10);
//   do_something(width, height); // Wrong order, but compile error!
//
// Note: The 'Tag' is a uique empty struct. If two instances of
// NamedType in the same namespace use the same struct name, they will
// be considered the same type. This is likely undesirable, so the Tag
// struct should be unique.
template <typename T, typename Tag>
class NamedType {
 public:
  // Explicit constructor from base type. (e.g. Height(10))
  explicit constexpr NamedType(T value) : value_(std::move(value)) {}

  // Move constructor. This is only available for instances of NamedType
  // where the base type T is not a reference.
  template <typename T_ = T, typename = IsNotReference<T_>>
  explicit constexpr NamedType(T&& value) : value_(std::move(value)) {}

  // Access the inner value of NamedType mutably.
  [[nodiscard]] constexpr T& get() { return value_; }

  // Access the inner value of NamedType immutably. (remove_reference_t
  // in the case where the contained type is a reference, this will
  // return a copy of the contained value).
  [[nodiscard]] constexpr std::remove_reference_t<T> const& get() const { return value_; }

  // Addition
  constexpr NamedType operator+(NamedType const& other) const {
    return NamedType(this->value_ + other.value_);
  }
  NamedType& operator+=(NamedType const& other) {
    this->value_ += other.value_;
    return this->value_;
  }
  constexpr NamedType operator+() const { return NamedType(+this->value_); }

  // Subtraction
  constexpr NamedType operator-(NamedType const& other) const {
    return NamedType(this->value_ - other.value_);
  }
  NamedType& operator-=(NamedType const& other) {
    this->value_ -= other.value_;
    return this->value_;
  }
  constexpr NamedType operator-() const { return NamedType(-this->value_); }

  // Printing
  void print(std::ostream& os) const { os << this->value_; }
  friend std::ostream& operator<<(std::ostream& os, const NamedType& other) {
    other.print(os);
    return os;
  }

 private:
  T value_;
};

}  // namespace cobalt::util

#endif  // COBALT_SRC_LIB_UTIL_NAMED_TYPE_H_
