GeneralPurpose-ValidOrderingPredicate

Provide a valid ordering predicate

Required inputs: IR

Comparison predicates used with STL containers and algorithms must establish strict weak ordering. This means the predicate must satisfy antisymmetry (if a < b, then b is not < a), transitivity (if a < b and b < c, then a < c), and irreflexivity (a < a must be false). Violating these rules causes undefined behavior, corrupted containers, and incorrect algorithm results.
Bad code (violates strict weak ordering):
struct Point {
  int x;
  int y;
};
struct BadComparator {
    bool operator()(Point a, Point b) const {
        return a.x < b.x || a.y < b.y;  // ERROR: not antisymmetric
    }
};
std::set<Point, BadComparator> s;
s.insert({1, 2});
s.insert({2, 1});  // Undefined behavior: set is corrupted
Good code (proper strict weak ordering):
struct GoodComparator {
    bool operator()(Point a, Point b) const {
        return std::tie(a.x, a.y) < std::tie(b.x, b.y); // OK: satisfies all requirements
    }
};

std::set<Point, GoodComparator> s;
s.insert({1, 2});
s.insert({2, 1});  // Works correctly
Good code (custom comparator for structs):
struct Record {
    int id;
    std::string name;
};

struct RecordComparator {
    bool operator()(const Record& a, const Record& b) const {
        return a.id < b.id;  // OK: properly defined ordering
    }
};

std::map<Record, std::string, RecordComparator> records;

Possible Messages

Key

Text

Severity

Disabled

valid_ordering_irreflexivity

‘{}’ does not provide strict weak order: Irreflexivity violation: comparator returns true for equal elements.

None

False

valid_ordering_transivity

‘{}’ does not provide strict weak order: Transitivity violation: Field ‘{}’ is compared if field ‘{}’ is {}, but not if ‘{}’ is {}.

None

False

Options

compare_template_positions

compare_template_positions

Type: dict[bauhaus.analysis.config.QualifiedName, int]

Default:

{
   'std::binary_search': 2,
   'std::equal_range': 2,
   'std::includes': 2,
   'std::inplace_merge': 1,
   'std::is_heap': 1,
   'std::is_heap_until': 1,
   'std::is_sorted': 1,
   'std::is_sorted_until': 2,
   'std::lexicographical_compare': 2,
   'std::lower_bound': 2,
   'std::make_heap': 1,
   'std::map': 2,
   'std::max': 1,
   'std::max_element': 1,
   'std::merge': 3,
   'std::min': 1,
   'std::min_element': 1,
   'std::minmax': 1,
   'std::minmax_element': 1,
   'std::multimap': 2,
   'std::multiset': 1,
   'std::next_permutation': 1,
   'std::nth_element': 1,
   'std::partial_sort': 1,
   'std::partial_sort_copy': 2,
   'std::pop_heap': 1,
   'std::prev_permutation': 1,
   'std::priority_queue': 2,
   'std::push_heap': 1,
   'std::set': 1,
   'std::set_difference': 3,
   'std::set_intersection': 3,
   'std::set_symmetric_difference': 3,
   'std::set_union': 3,
   'std::sort': 1,
   'std::sort_heap': 1,
   'std::stable_sort': 1,
   'std::upper_bound': 2
}
Positions (zero based) of key comparison predicate template argument.