Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component bdldfp_uint128
[Package bdldfp]

Provide a representation of a 128-bit int for bitwise operations. More...

Namespaces

namespace  bdldfp

Detailed Description

Outline
Purpose:
Provide a representation of a 128-bit int for bitwise operations.
Classes:
bdldfp::Uint128 A representation of a 128-bit unsigned integer
See also:
bsl::bitset
Description:
This component provides a value-semantic type, bdldfp::Uint128, that is used to represent a 128-bit unsigned integer having host-native byte order. This component also provides a set of useful bitwise manipulation operators for this type.
Usage:
This section illustrates intended use of this component.
Example 1: Representing a 128 bit pattern for IPv6:
Starting in 1996, the world's TCP/IP infrastructure started the move to a 128-bit addressing scheme, IPv6. IPv4 had a useful quality in that it could be represented by a single 32-bit machine word for internal routing purposes. With IPv6, the need arises to manipulate 128-bit values representing IPv6 addresses for similar routing purposes.
Suppose we need to write a function that needs to take 128-bit addresses indicating downstream routers in our network.
First, we forward declare the "addRouter" function that takes an IPv6 address indicating a router, and an IPv6 network address (a partial IP address, with trailing 0's) that the router covers:
  void addRouter(bdldfp::Uint128 router, bdldfp::Uint128 network);
Now we create a function that loads a set of networks and routers:
  void setupNetwork()
  {
      bdldfp::Uint128 network;
      network.setHigh(0x4242000042420000L);
      network.setLow(0x0);

      bdldfp::Uint128 router(0x000012345678ABCDL, 0xDCBA000087654321L);
Finally we invoke addRouter, on our network and router.
      addRouter(router, network);
  }
Notice that Uint128 values can be created from high/low pairs.
Example 2: Checking a 128-bit IPv6 Network Mask:
In networks, checking a network mask is a fundamental operation. A 128-bit mask can be used to indicate if an address is in a network, and where in the network an address is.
Suppose we need to decide if an address is within a network, and extract the sub-address from the IPv6 address.
First, we define a function that checks a passed IPv6 address and indicates the sub-address, and network membership:
  bool checkNetworkAddress(bdldfp::Uint128 *subAddress,
                           bdldfp::Uint128  network,
                           int              maskLength
                           bdldfp::Uint128  address)
 {
Then, we compute a net mask for the specified maskLength:
      bdldfp::Uint128 netMask;
      for (int i = 0; i < maskLength; ++i) {
          netMask |= 1;
          if (i != maskLength - 1) {
              netMask <<= 1;
          }
      }
Notice that it is possible to shift Uint128 values as if they were a native type. Meaning that it is possible to shift a Uint128 by 64-bits, or more, in single operation, because Uint128 functions just like a built-in 128-bit integer type would.
Next, we calculate whether the passed address is within the network:
      bool inNetwork = network == (address & ~netMask);
Then, we compute the subAddress, if the address is in the network:
      if (inNetwork) {
          *subAddress = address & netMask;
      }
Now, we return whether the address is in the network, and close the function:
      return inNetwork
  }
Finally, we call checkNetworkAddress on a test network and address:
  bdldfp::Uint128 subAddress;
  assert(checkNetworkAddress(
              &subAddress,
              bdldfp::Uint128(0xABCD424200001234L,0x22FF12345678L),
              bdldfp::Uint128(0xABCD424200001234L,0x22FF00000000L),
              32); // The network has a 32-bit internal address mask.
  assert(subAddress == 0x12345678L);
Notice that primitive 64-bit words can be promoted to 128-bit addresses.