• Jason Rhinelander's avatar
    Improve constructor/destructor tracking · 3f589379
    Jason Rhinelander authored
    This commit rewrites the examples that look for constructor/destructor
    calls to do so via static variable tracking rather than output parsing.
    
    The added ConstructorStats class provides methods to keep track of
    constructors and destructors, number of default/copy/move constructors,
    and number of copy/move assignments.  It also provides a mechanism for
    storing values (e.g. for value construction), and then allows all of
    this to be checked at the end of a test by getting the statistics for a
    C++ (or python mapping) class.
    
    By not relying on the precise pattern of constructions/destructions,
    but rather simply ensuring that every construction is matched with a
    destruction on the same object, we ensure that everything that gets
    created also gets destroyed as expected.
    
    This replaces all of the various "std::cout << whatever" code in
    constructors/destructors with
    `print_created(this)`/`print_destroyed(this)`/etc. functions which
    provide similar output, but now has a unified format across the
    different examples, including a new ### prefix that makes mixed example
    output and lifecycle events easier to distinguish.
    
    With this change, relaxed mode is no longer needed, which enables
    testing for proper destruction under MSVC, and under any other compiler
    that generates code calling extra constructors, or optimizes away any
    constructors.  GCC/clang are used as the baseline for move
    constructors; the tests are adapted to allow more move constructors to
    be evoked (but other types are constructors much have matching counts).
    
    This commit also disables output buffering of tests, as the buffering
    sometimes results in C++ output ending up in the middle of python
    output (or vice versa), depending on the OS/python version.
    3f589379
example-buffers.ref 553 Bytes