/**
 * @file doxygen-group.h
 * Just an example.
 */

class A {
public:
	unsigned n;
	friend bool operator==(const A& lhs, const A& rhs);
	friend bool operator==(const A& lhs, const unsigned& rhs);
	
	A& operator+=(const A& rhs);
	A& operator+=(const unsigned& rhs);
};

/// @name Comparison for A
/// @{
/**
 * Comparison operators.
 */
bool operator==(const A& lhs, const A& rhs) {
	return lhs.n == rhs.n;
}
bool operator==(const A& lhs, const unsigned& rhs) {
	return lhs.n == rhs;
}
/// @}

/// @name Addition for A
/// @{
/**
 * Addition operators.
 */
A& operator+=(const A& rhs) {
	this->n += rhs.n;
	return *this;
}
A& operator+=(const unsigned& rhs) {
	this->n += rhs;
	return *this;
}
/// @}

class B {
public:
	unsigned n;
	/// @name Comparison for B
	/// @{
	/**
	 * Comparison operators.
	 */
	friend bool operator==(const B& lhs, const B& rhs);
	friend bool operator==(const B& lhs, const unsigned& rhs);
	/// @}
	
	/// @name Addition for B
	/// @{
	/**
	 * Addition operators.
	 */
	B& operator+=(const B& rhs);
	B& operator+=(const unsigned& rhs);
	/// @}
};

bool operator==(const B& lhs, const B& rhs) {
	return lhs.n == rhs.n;
}
bool operator==(const B& lhs, const unsigned& rhs) {
	return lhs.n == rhs;
}

B& operator+=(const B& rhs) {
	this->n += rhs.n;
	return *this;
}
B& operator+=(const unsigned& rhs) {
	this->n += rhs;
	return *this;
}

template<typename T>
class C {
public:
	unsigned n;
	friend bool operator==(const C<T>& lhs, const C<T>& rhs);
	friend bool operator==(const C<T>& lhs, const unsigned& rhs);
	
	C<T>& operator+=(const C<T>& rhs);
	C<T>& operator+=(const unsigned& rhs);
};

/// @name Comparison for C
/// @{
/**
 * Comparison operators.
 */
template<typename T>
bool operator==(const C<T>& lhs, const C<T>& rhs) {
	return lhs.n == rhs.n;
}
template<typename T>
bool operator==(const C<T>& lhs, const unsigned& rhs) {
	return lhs.n == rhs;
}
/// @}

/// @name Addition for C
/// @{
/**
 * Addition operators.
 */
template<typename T>
C<T>& operator+=(const unsigned& rhs) {
	this->n += rhs;
	return *this;
}
template<typename T>
C<T>& operator+=(const C<T>& rhs) {
	this->n += rhs.n;
	return *this;
}
/// @}

template<typename T>
class D {
public:
	unsigned n;
	/// @name Comparison for D
	/// @{
	/**
	 * Comparison operators.
	 */
	friend bool operator==(const D<T>& lhs, const D<T>& rhs);
	friend bool operator==(const D<T>& lhs, const unsigned& rhs);
	/// @}
	
	/// @name Addition for D
	/// @{
	/**
	 * Addition operators.
	 */
	D<T>& operator+=(const D<T>& rhs);
	D<T>& operator+=(const unsigned& rhs);
	/// @}
};

template<typename T>
bool operator==(const D<T>& lhs, const D<T>& rhs) {
	return lhs.n == rhs.n;
}
template<typename T>
bool operator==(const D<T>& lhs, const unsigned& rhs) {
	return lhs.n == rhs;
}

template<typename T>
D<T>& operator+=(const D<T>& rhs) {
	this->n += rhs.n;
	return *this;
}
template<typename T>
D<T>& operator+=(const unsigned& rhs) {
	this->n += rhs;
	return *this;
}