December 26th, 2018

Don’t forget: std::pair does lexicographical ordering, so you don’t have to

A feature perhaps not as widely known as I thought is that the std::pair type performs lexicographical ordering, so you don’t have to.

// Suppose we record versions as std::pair<int, int>
// where the first is the major version
// and the second is the minor version.

std::map<ComponentId, std::pair<int, int>> requiredVersions;

bool IsSupported(ComponentId id, std::pair<int, int> actualVersion)
{
 auto item = requiredVersions.find(id);
 if (item == requiredVersions.end()) {
  return true;
 }

 auto& requiredVersion = item->second;

 if (actualVersion.first > requiredVersion.first ||
     (actualVersion.first == requiredVersion.first &&
      actualVersion.second >= requiredVersion.second)) {
  return true;
 }

 return false;
}

First, we try to find the component in our list of required versions. If it’s not found, then the component has no version requirements, and we say, “Sure, it’s supported!” (This is just an example. Maybe you want to say that if it’s not on the list, then it’s not supported at all.)

Otherwise, we check the actual version number against the required version. If the major version is greater, or if the major version is equal but the minor version is greater or equal, then we decide that we have met the minimum requirements.

Writing the comparison of major and minor versions is easy to get wrong,

So don’t write the code that’s easy to get wrong. Let the standard library do it.

bool IsSupported(ComponentId id, std::pair<int, int> actualVersion)
{
  auto item = requiredVersions.find(id);
 if (item == requiredVersions.end()) {
  return true;
 }

 auto& requiredVersion = item->second;

 return actualVersion >= requiredVersion;
}

Bonus chatter: I saw this mistake in some code that used the std::pair as the key in a map.

std::map<std::pair<int, int>, CoolThing> sortedThings;

The idea is that the cool things would be sorted by a sort key that behaved like major/minor. The code compared the keys manually, presumably because the author didn’t think that std::pair supported the relational operators.

But of course std::pair supports the relational operators bcause that’s one of the prerequisites for being the key of a std::map. (Okay, technically, std::map requires only operator<, but once you have operator<, you can synthesize the rest.)

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments

Discussion are closed.