I don't think there is a suitable predefined algorithm in the standard library that does this. In particular, std::adjacent_find
could be used for this if you were to define a relatively complex and stateful predicate for it, but that would really amount to misusing std::adjacent_find
as some kind of replacement for std::for_each
, i.e. it would not have much to do with the original purpose of std::adjacent_find
.
However, instead of naked pointers, you should be using iterators. I'd also suggest putting the checking code into a separate function, perhaps named check
. Here is what I would suggest:
#include <vector>
#include <map>
#include <iostream>
bool check(const std::vector<std::map<double,double>> &v)
{
/* Fast-forward to the first non-empty entry. */
auto it = begin(v);
for( ; it != end(v) ; ++it)
if (!it->empty())
break;
/* We might be done by now. */
if (it == end(v))
return true;
/* Else, go through the remaining entries,
skipping empty maps. */
auto prev = it->end();
advance(prev,-1);
++it;
for ( ; it != end(v) ; ++it)
{
if (!it->empty())
{
if (it->begin()->first < prev->first)
return false;
prev = it->end();
advance(prev,-1);
}
}
return true;
}
int main()
{
std::vector<std::map<double,double>> v;
/* Two entries for the vector, invalid order. */
v.push_back({ {1.0,1.0} , {2.0,4.0} });
v.push_back({ {3.0,9.0} , {1.0,16.0} });
if (!check(v))
throw std::runtime_error("Invalid order of the maps in the vector.");
return 0;
}
Note: It would be even more C++-like (or, at least more like the algorithms in the standard library) if you were to define the check
function as an algorithm that takes a range of iterators, rather than a reference to a container, as argument. Rewriting the function to match this concept is straight-forward.
Note 2: The advantage of using iterators instead of naked pointers is that you get a better and cleaner abstraction of what you need: Something that references an item in the map, whereas a double*
pointer could be pointing to all kinds of things. However, there is also a disadvantage of using iterators: If you were to modify your algorithm such that it alters maps while iterating through the vector, the iterator may be invalidated, whereas the pointer would not (unless you delete the element it points to). (The pointers might be invalidated if you alter the vector, though.)
But as long as the checking procedure is only used for checking and nothing else (which my code indicates by putting the code into a separate function dedicated to this purpose, and by taking the vector as a const-reference), iterator invalidation is not an issue.