module;
#include <iostream>
#include <string>

export module Address;

// Definition der Klasse für die Adressdaten
export class Address
{
    std::string name;     // Name
    std::string location; // Ort
public:
    Address() = default; // ctor, hat nichts zu tun
    // ctor mit Daten
    Address(std::string_view _name, std::string_view _loc);
    // copy-ctor
    Address(const Address& obj2) = default;
    // Move-Konstruktor
    Address(Address&& obj2);
    // Move-Operator =
    Address& operator = (Address&& obj);
    // Überladener Zuweisungsoperator
    Address& operator = (const Address& obj2);
    // Adressdaten setzen
    void SetData(const char* const pN, const char* const pL);
    // Überladener << Operator für Ausgabe
    friend std::ostream& operator << (std::ostream& os, const Address& obj2);
    // Überladener > Operator für Vergleich
    bool operator > (const Address& obj2) const;
};
// Definition der Memberfunktionen
// ctor
Address::Address(std::string_view _name, std::string_view _loc):
    name(_name), location(_loc)
{ }
// Move-Konstruktor
Address::Address(Address&& obj2)
{
    // Eigenschaften transferieren
    name = std::move(obj2.name);
    location = std::move(obj2.location);
    // Quell-Objekt in gueltigen Zustand versetzen
    // std::strings move-ctor setzt das Quellstring-Objekt
    // in einen gueltigen Zustand. Sicherheitshalber
    // koennen die Quellstrings auch 'geleert' werden
    //obj2.name.clear();
    //obj2.location.clear();
}
// Move-Operator =
Address& Address::operator = (Address&& obj2)
{
    // Eigenschaften transferieren
    name = std::move(obj2.name);
    location = std::move(obj2.location);
    // Quellstrings sind nach string-moves
    // in einem gueltigen Zustand
    return *this;
}
// Setzen der Adressdaten
void Address::SetData(const char* const pN, const char* const pL)
{
    name = pN;
    location = pL;
}
// Vergleichoperator ueberladen fuer Vergleich
// innerhalb der Templatefunktion Sort(...)
inline bool Address::operator > (const Address& obj2) const
{
    return (name > obj2.name);
}
// Zuweisungsoperator ueberladen fuer Zuweisungen
// innerhalb der Templatefunktion Swap(...)
Address& Address::operator = (const Address& obj2)
{
    if (&obj2 == this)
        return *this;
    name = obj2.name;
    location = obj2.location;
    return *this;
}

// Ueberladener Operator << fuer Ausgabe
export std::ostream& operator << (std::ostream& os, const Address& addr)
{
    std::println(os,"Name: {}, Ort: {}", addr.name, addr.location);
    return os;
}
