/** @file data_type.hpp
 *
 *  @author Cory Alexander Balaton (coryab)
 *  @author Janita Ovidie Sandtrøen Willumsen (janitaws)
 *
 *  @version 1.0
 *
 *  @brief Header for the data_t type.
 *
 *  @bug No known bugs
 * */
#ifndef __DATA_TYPE__
#define __DATA_TYPE__

#include <sys/types.h>
#include <type_traits>

/** @brief Data structure that contains the data needed for the project*/
struct data_t {
    double E = 0.; ///< The expected energy
    double M = 0.; ///< The expected magnetization
    double E2 = 0.; ///< The expected variance of the energy
    double M2 = 0.; ///< The expected variance of magnetization
    double M_abs = 0.; ///< The expected absolute magnetization
};

/** @brief Define dividing data_t by a number
 *
 *  @param data The data to divide
 *  @param num The number to divide data by
 *
 *  @return data_t
 * */
template <class T>
data_t operator/(const data_t &data, T num);

// Explicit instantiation
extern template data_t operator/(const data_t &, uint);
extern template data_t operator/(const data_t &, ulong);
extern template data_t operator/(const data_t &,int);
extern template data_t operator/(const data_t &,double);


/** @brief Define /= on data_t by a number.
 *
 *  @param data The data to divide
 *  @param num The number to divide data by
 *
 *  @return data_t
 * */
template <class T>
data_t& operator/=(data_t &data, T num);

// Explicit instantiation
extern template data_t& operator/=(data_t &, uint);
extern template data_t& operator/=(data_t &, ulong);
extern template data_t& operator/=(data_t &,int);
extern template data_t& operator/=(data_t &,double);

/** @brief Define + on data_t by a data_t.
 *
 *  @param a The left side
 *  @param b The right side
 *
 *  @return data_t
 * */
data_t operator+(const data_t &a, const data_t &b);

/** @brief Define += on data_t by a data_t.
 *
 *  @param a The left side
 *  @param b The right side
 *
 *  @return data_t
 * */
data_t& operator+=(data_t &a, const data_t &b);

#endif
