#include <iostream>
#include <vector>

template <typename Tag, typename T>
struct StrongAlias {
    // Other C'tors, for r-value etc...
    StrongAlias(const T& value)
        : value_(value) {}

    const T& operator*() const { return value_; }
    T& operator*() { return value_; }

    // Need to add hash function and operator<<
    auto operator<=>(const StrongAlias& other) const = default;

private:
    T value_;
};

using IpV4 = StrongAlias<class IpV4Tag, std::string>;
using IpV6 = StrongAlias<class IpV6Tag, std::string>;
using MacAddress = StrongAlias<class MacAddressTag, std::string>;

class Streamer {
public:
    using IpAddress = std::string;
    using Port = uint16_t;
    using Vlan = uint16_t;

    struct StreamInfo {
        IpAddress sourceAddress_;
        IpAddress destinationAddress_;
        Port sourcePort_;
        Port destinationPort_;
        Vlan vlan_;
    };

    Streamer(std::initializer_list<StreamInfo> info)
        : info_(info) {
    }

    Streamer(const StreamInfo& info)
        : info_{info} {
    }

private:
    std::vector<StreamInfo> info_;
};

struct I {};
struct A : I {};
struct B : I {};

struct Foo {
    Foo(I* inter): inter_(inter) {}

    I* inter_;
}

int main() {
    Streamer streamer({"192.168.0.0", "192.168.10.24", 5432, 5432, 12});
    Streamer streamer2{};

    IpV4 ip{"192.168.0.1"};
    IpV4 ip2{"192.168.0.2"};

    std::cout << std::boolalpha << (ip < ip2) << '\n';
    std::cout << std::boolalpha << (ip > ip2) << '\n';
    std::cout << std::boolalpha << (ip != ip2) << '\n';
    std::cout << std::boolalpha << (ip == ip2) << '\n';
}