#ifndef NAN_HELPER_HPP
#define NAN_HELPER_HPP

#include <utils/PugsMacros.hpp>

#include <cmath>
#include <iostream>
#include <type_traits>

template <typename T>
class NaNHelper
{
 private:
  const T& m_t;

 public:
  PUGS_INLINE
  friend std::ostream&
  operator<<(std::ostream& os, const NaNHelper<T>& helper)
  {
    if constexpr (std::is_arithmetic_v<T>) {
      if (std::isnan(helper.m_t)) {
        os << "nan";
      } else {
        os << helper.m_t;
      }
    } else {
      os << helper.m_t;
    }
    return os;
  }

  PUGS_INLINE
  explicit NaNHelper(const T& t) : m_t{t} {}

  NaNHelper(NaNHelper&&)      = delete;
  NaNHelper(const NaNHelper&) = delete;

  NaNHelper()  = delete;
  ~NaNHelper() = default;
};

#endif   // NAN_HELPER_HPP