I have this function we wrote some time ago:
template <class C, class T>
static inline bool findClosestObject( const C& container, const TimeUnit& now, T& object );
C
is a container of T elementsTimeUnit
is a class encapsulating date and timeT
is an object with aTimeUnit
information
This function does a binary search (using std::lower_bound
) in the container to find the closest object to now
.
As we do a binary search, the container must be sorted. This function is used with many kind of containers (C
can be std::vector
, std::set
, std::map
...) in many places. Sometimes we use sorted std::vector
rather than std::set
because their memory management is faster and also for historical issue and compatibility with other piece of your code which is using vectors.
Problem is that I found a place in the code where a developer called findClosestObject
with a container that was not sorted....nice bug...and I cannot safely identify all places where this could have been done.
So I now need to prevent that by sorting the container in this specific case where it's not (will be slow but will at least work and guarantee function returns what we want it to return)
So I tried to modify my function:
template <class C, class T>
static inline const C& fixOrder( const C& container, C& temp )
{
if ( std::is_sorted( container.begin(), container.end() )
{
return container;
}
else
{
assert( false ); // to alert developper
// in Release, fix the issue to have function work!
temp = container;
std::sort( temp.begin(), temp.end() );
return temp;
}
}
template <class C, class T>
static inline bool findClosestObject( const C& originalContainer, const TimeUnit& now, T& object )
{
C temp;
const C& container = fixOrder( originalContainer, temp );
...
// leave old code unchanged
}
But this fails to compile when C
is a std::set
or a std::map
. Because std::sort
is not allowed for those kind of containers...
Can fixOrder
be written in such a way that it would only do things for std::vector
and not for other containers?