public Iterable<CidrBlock> iterableCidrs() {
        return () -> new Iterator<>() {
            private final BigInteger increment = BigInteger.ONE.shiftLeft(suffixLength());
            private final BigInteger maxValue = BigInteger.ONE.shiftLeft(addressLength).subtract(increment);
            private BigInteger current = addressInteger;

            public boolean hasNext() {
                return current.compareTo(maxValue) < 0;
            }

            public CidrBlock next() {
                if (!hasNext()) throw new NoSuchElementException();
                CidrBlock cidrBlock = new CidrBlock(current, prefixLength, addressLength);
                current = current.add(increment);
                return cidrBlock;
            }
        };
    }
@Test
    public void iterableCidrs() {
        CidrBlock superBlock = CidrBlock.fromString("10.12.14.0/24");
        assertEquals(List.of("10.12.14.200/29", "10.12.14.208/29", "10.12.14.216/29", "10.12.14.224/29", "10.12.14.232/29", "10.12.14.240/29", "10.12.14.248/29"),
                StreamSupport.stream(CidrBlock.fromString("10.12.14.200/29").iterableCidrs().spliterator(), false)
                        .takeWhile(superBlock::overlapsWith)
                        .map(CidrBlock::asString)
                        .collect(Collectors.toList()));

        assertEquals(StreamSupport.stream(superBlock.iterableIps().spliterator(), false)
                        .skip(24)
                        .map(ip -> InetAddressUtil.toString(ip) + "/32")
                        .collect(Collectors.toList()),
                StreamSupport.stream(CidrBlock.fromString("10.12.14.24/32").iterableCidrs().spliterator(), false)
                        .takeWhile(superBlock::overlapsWith)
                        .map(CidrBlock::asString)
                        .collect(Collectors.toList()));
    }