Home > Back-end >  Overload operator to increase IP addresses on boost::asio::ip
Overload operator to increase IP addresses on boost::asio::ip

Time:05-28

I would like to do math operations with IP addresses from boost::asio. Specifically I need to increment and/or add a given integer on an existing address to ease IP list generation in a software that I'm writing.

As today I'm using custom classes to handle IP addresses and networks, but I would like to move to boost::asio so I can rely on them to properly check/validade addresses and network attributes.

I have this working code as example (except for the operator part):

using boost::asio::ip::make_address_v4;
using boost::asio::ip::address_v4;

auto add(const address_v4& address, std::size_t value = 1) {
    return make_address_v4(address.to_uint()   value);
}

// This is definitely wrong
auto operator (std::size_t value, const address_v4& address) {
    return add(address, value);
}

int main() {
    auto ip1 = make_address_v4("192.168.1.1");
    fmt::print("IP address: {}\n", ip1.to_string());

    auto ip2 = make_address_v4(ip1.to_uint()   1);
    fmt::print("IP address: {}\n", ip2.to_string());

    // Add function
    fmt::print("Added IP: {}\n", add(ip2, 8).to_string());
    fmt::print("Added IP: {}\n", add(ip2).to_string());

    // operator 
    fmt::print("Added IP: {}\n", (ip2   4).to_string());

    return 0;
}

add function works as expected, but I don't know how to overload it so I can do things like: ip or ip 4.

Also is there a better way to do math with boost::asio::ip::address_v4? I'm always getting values as uint and doing the math there.

Another solution that I was thinking was to inherit boost::asio::ip::address_v4 and create the custom operators, but I don't know if this would work and if it works, this seems overkill, or even worse, I don't know if this is a good practice, it looks like it doesn't.

Thank you.

CodePudding user response:

To technically work you need the overload:

// This is morally wrong
auto operator (const address_v4& address, std::size_t value) {
    return add(address, value);
}

That's because the left-hand operand is address_v4, not size_t.

Live demo

However, please don't do this. See e.g. What are the basic rules and idioms for operator overloading?. There is no clear and undisputed meaning of the operation here. There is much room for surprises. Depending on subnetting, incrementing an address can make a regular address into a broadcast address, or even cross over into different subnets.

E.g. "10.10.9.254" 0x01010101 == 11.11.10.255 makes little sense, and "255.255.255.255" 0x01010101 == "1.1.1.0" even less.

What you probably want here is a subnet-aware enumerator/iterator interface, perhaps even with random sampling if you need non-sequential traversal. If you abstract this away as if address_v4 is "just an arithmetic type" you're lying about your domain information.

  • Related