/probe

C++ type to aid unit testing of memory leaks/moves/copies inside of containers

Primary LanguageC++MIT LicenseMIT

probe

C++ type to aid unit testing of memory leaks/moves/copies inside of containers

For full API info, check the source file.

Example

This shows how the probe is used to inspect what an std::vector is doing to the contents

#include "include/probe.hpp"
#include <vector>
#include <iostream>
#include <cassert>

int main()
{
    using probe = pr::probe_t<int>; //we want to use it with ints as underlying values

    probe::reset(); //resets all metrics that is stored in class static storage

    std::vector<probe> numbers;

    numbers.push_back({});

    assert(numbers.back() == 0); //can be converted back to value

    pr::probe_counts c = probe::last(); //returns all counts of events happened since last time last()/reset() was called

    assert(c.copies == 0); //that should not have invoked copies
    assert(c.moves > 0); //that should have invoked moves

    //print all events as text
    std::cout << "after push_back:\n" + to_string(c) << "\n\n";

    numbers.emplace_back();

    {
        probe p = std::move(numbers[0]);
    }

    pr::probe_state s = probe::state();
    assert(s.existing == 2); //2 instances should be existing at this point (has active lifetime. ends with destructor)
    assert(s.active == 1); //1 instance should be active at this point (holds meaningful value. ends by being moved from, or destructed)

    c = probe::last();

    std::cout << "after emplace_back:\n" + to_string(c) << "\n\n";

    numbers.insert(numbers.begin(), probe{});

    c = probe::last();
    std::cout << "after insert:\n" + to_string(c) << "\n\n";

    numbers.pop_back();

    c = probe::last();

    assert(c.destr == 1); //should have called 1 destructor

    std::cout << "after pop_back:\n" + to_string(c) << "\n\n";

    numbers.clear();

    c = probe::last();
    std::cout << "after clear:\n" + to_string(c) << "\n\n";

    assert(probe::clean()); //clean returns true if there are exactly 0 `existing` and `active` items. i.e. no leaks nor double deletes

    //prints a summary of the current state
    std::cout << "final report:\n" << probe::report() << "\n";
}

Possible output

after push_back:
-calls-
 default constructor: 1
 value constructor:   0
 copy constructor:    0
 move constructor:    1
 copy assignment:     0
 move assignment:     0
 destructor:          1
-semantics-
 copies:              0
 moves:               1
-min/max-
 min active:          0
 max active:          1
 min existing:        0
 max existing:        2

after emplace_back:
-calls-
 default constructor: 1
 value constructor:   0
 copy constructor:    0
 move constructor:    2
 copy assignment:     0
 move assignment:     0
 destructor:          2
-semantics-
 copies:              0
 moves:               2
-min/max-
 min active:          0
 max active:          2
 min existing:        0
 max existing:        3

after insert:
-calls-
 default constructor: 1
 value constructor:   0
 copy constructor:    0
 move constructor:    3
 copy assignment:     0
 move assignment:     0
 destructor:          3
-semantics-
 copies:              0
 moves:               3
-min/max-
 min active:          0
 max active:          2
 min existing:        0
 max existing:        6

after pop_back:
-calls-
 default constructor: 0
 value constructor:   0
 copy constructor:    0
 move constructor:    0
 copy assignment:     0
 move assignment:     0
 destructor:          1
-semantics-
 copies:              0
 moves:               0
-min/max-
 min active:          0
 max active:          1
 min existing:        0
 max existing:        2

after clear:
-calls-
 default constructor: 0
 value constructor:   0
 copy constructor:    0
 move constructor:    0
 copy assignment:     0
 move assignment:     0
 destructor:          2
-semantics-
 copies:              0
 moves:               0
-min/max-
 min active:          0
 max active:          0
 min existing:        0
 max existing:        1

final report:
===LAST===
-calls-
 default constructor: 0
 value constructor:   0
 copy constructor:    0
 move constructor:    0
 copy assignment:     0
 move assignment:     0
 destructor:          0
-semantics-
 copies:              0
 moves:               0
-min/max-
 min active:          0
 max active:          0
 min existing:        0
 max existing:        0
===TOTAL===
-calls-
 default constructor: 3
 value constructor:   0
 copy constructor:    0
 move constructor:    6
 copy assignment:     0
 move assignment:     0
 destructor:          9
-semantics-
 copies:              0
 moves:               6
-min/max-
 min active:          0
 max active:          2
 min existing:        0
 max existing:        6
===STATE===
active:   0
existing: 0