Sequoia
Loading...
Searching...
No Matches
Classes | Namespaces | Typedefs | Enumerations | Functions | Variables
SemanticsCheckersDetails.hpp File Reference

Implementation details for semantics checks that cleanly supports types which do/do not have allocators. More...

#include "sequoia/TestFramework/TestLogger.hpp"
#include "sequoia/TestFramework/Advice.hpp"
#include "sequoia/TestFramework/FreeCheckers.hpp"
#include "sequoia/Core/Meta/Concepts.hpp"
#include <compare>
#include <format>
#include <optional>

Go to the source code of this file.

Classes

struct  sequoia::testing::impl::do_swap<>
 
struct  sequoia::testing::impl::null_mutator
 
struct  sequoia::testing::impl::auxiliary_data_policy< T >
 
struct  sequoia::testing::impl::auxiliary_data< T >
 

Namespaces

namespace  sequoia::testing::impl
 Condition for applying a container check.
 

Typedefs

template<comparison_flavour C>
using sequoia::testing::comparison_constant = std::integral_constant< comparison_flavour, C >
 
using sequoia::testing::equality_type = comparison_constant< comparison_flavour::equality >
 
using sequoia::testing::inequality_type = comparison_constant< comparison_flavour::inequality >
 
using sequoia::testing::less_than_type = comparison_constant< comparison_flavour::less_than >
 
using sequoia::testing::greater_than_type = comparison_constant< comparison_flavour::greater_than >
 
using sequoia::testing::leq_type = comparison_constant< comparison_flavour::leq >
 
using sequoia::testing::geq_type = comparison_constant< comparison_flavour::geq >
 
using sequoia::testing::threeway_type = comparison_constant< comparison_flavour::threeway >
 
template<class T >
using sequoia::testing::optional_ref = std::optional< std::reference_wrapper< T > >
 

Enumerations

enum class  comparison_flavour {
  equality , inequality , less_than , greater_than ,
  leq , geq , threeway
}
 

Functions

std::string sequoia::testing::to_string (const comparison_flavour f)
 
template<test_mode Mode, class T , class U >
requires equivalence_checkable_for_semantics<Mode, T, U>
void sequoia::testing::impl::check_best_equivalence (test_logger< Mode > &logger, const T &x, const T &y, const U &xEquivalent, const U &yEquivalent)
 
template<test_mode Mode, comparison_flavour C, class Actions , movable_comparable T, invocable_r< bool, T > Fn, class... Args>
bool sequoia::testing::impl::do_check_comparison_consistency (test_logger< Mode > &logger, comparison_constant< C > comparison, const Actions &actions, const T &x, std::string_view tag, Fn fn, const Args &... args)
 
template<test_mode Mode, comparison_flavour C, class Actions , movable_comparable T, invocable_r< bool, T > Fn>
bool sequoia::testing::impl::check_comparison_consistency (test_logger< Mode > &logger, comparison_constant< C > comparison, const Actions &actions, const T &x, const T &y, Fn fn)
 
template<test_mode Mode, class Actions , std::totally_ordered T, class... Args>
bool sequoia::testing::impl::check_ordering_operators (test_logger< Mode > &logger, const Actions &actions, const T &x, const T &y, const Args &... args)
 
template<test_mode Mode, class Actions , std::totally_ordered T, class... Args>
bool sequoia::testing::impl::check_ordering_consistency (test_logger< Mode > &logger, const Actions &actions, const T &x, const T &y, const Args &... args)
 
template<test_mode Mode, class Actions , std::totally_ordered T, class U , class... Args>
bool sequoia::testing::impl::check_ordering_consistency (test_logger< Mode > &logger, const Actions &actions, const T &x, const T &y, const U &, const U &, const Args &... args)
 
template<test_mode Mode, class Actions , std::equality_comparable T, class... Args>
bool sequoia::testing::impl::check_equality_prerequisites (test_logger< Mode > &logger, const Actions &actions, const T &x, const T &y, const Args &... args)
 
template<test_mode Mode, std::equality_comparable T, class U >
requires checkable_against_for_semantics<Mode, T, U>
bool sequoia::testing::impl::check_against (std::string message, test_logger< Mode > &logger, const T &x, const U &xEquivalent)
 
template<test_mode Mode, class Actions , std::equality_comparable T, class U , class... Args>
bool sequoia::testing::impl::check_equality_prerequisites (test_logger< Mode > &logger, const Actions &actions, const T &x, const T &y, const U &xEquivalent, const U &yEquivalent, const Args &... args)
 
template<test_mode Mode, class Actions , std::totally_ordered T, class... Args>
bool sequoia::testing::impl::check_orderable_prerequisites (test_logger< Mode > &logger, const Actions &actions, const T &x, const T &y, const Args &... args)
 
template<test_mode Mode, class Actions , movable_comparable T, class U , class V , class... Args>
requires checkable_against_for_semantics<Mode, T, U> && checkable_against_for_semantics<Mode, T, V>
std::optional< T > sequoia::testing::impl::do_check_move_construction (test_logger< Mode > &logger, const Actions &actions, T &&z, const U &y, optional_ref< const V > movedFrom, const Args &... args)
 
template<test_mode Mode, class Actions , movable_comparable T, class U , class V >
requires checkable_against_for_semantics<Mode, T, U>
std::optional< T > sequoia::testing::impl::check_move_construction (test_logger< Mode > &logger, const Actions &actions, T &&z, const U &y, optional_ref< const V > movedFrom)
 
template<test_mode Mode, class Actions , movable_comparable T, class U , class V , std::invocable< T & > Mutator, class... Args>
requires checkable_against_for_semantics<Mode, T, U> && checkable_against_for_semantics<Mode, T, V>
void sequoia::testing::impl::do_check_move_assign (test_logger< Mode > &logger, const Actions &actions, T &z, T &&y, const U &yEquivalent, optional_ref< const V > movedFrom, Mutator &&yMutator, const Args &... args)
 
template<test_mode Mode, class Actions , movable_comparable T, class U , class V , std::invocable< T & > Mutator>
requires checkable_against_for_semantics<Mode, T, U> && checkable_against_for_semantics<Mode, T, V>
void sequoia::testing::impl::check_move_assign (test_logger< Mode > &logger, const Actions &actions, T &z, T &&y, const U &yEquivalent, optional_ref< const V > movedFrom, Mutator m)
 
template<test_mode Mode, class Actions , movable_comparable T, class U , class... Args>
requires checkable_against_for_semantics<Mode, T, U>
bool sequoia::testing::impl::do_check_swap (test_logger< Mode > &logger, const Actions &actions, T &&x, T &&y, const U &xEquivalent, const U &yEquivalent, const Args &... args)
 
template<test_mode Mode, class Actions , movable_comparable T, class U >
requires checkable_against_for_semantics<Mode, T, U>
bool sequoia::testing::impl::check_swap (test_logger< Mode > &logger, const Actions &actions, T &&x, T &&y, const U &xEquivalent, const U &yEquivalent)
 
template<test_mode Mode, class Actions , pseudoregular T, class U , std::invocable< T & > Mutator>
requires checkable_against_for_semantics<Mode, T, U>
bool sequoia::testing::impl::check_swap (test_logger< Mode > &logger, const Actions &actions, T &&x, T &&y, const U &xEquivalent, const U &yEquivalent, Mutator yMutator)
 
template<test_mode Mode, class Actions , movable_comparable T, class... Args>
requires (serializable_to<T, std::stringstream> && deserializable_from<T, std::stringstream>)
bool sequoia::testing::impl::do_check_serialization (test_logger< Mode > &logger, const Actions &actions, T &&u, const T &y, const Args &... args)
 
template<test_mode Mode, class Actions , movable_comparable T>
requires (serializable_to<T, std::stringstream> && deserializable_from<T, std::stringstream>)
bool sequoia::testing::impl::check_serialization (test_logger< Mode > &logger, const Actions &actions, T &&u, const T &y)
 

Variables

template<test_mode Mode, std::equality_comparable T, class U >
constexpr bool sequoia::testing::checkable_against_for_semantics
 
template<test_mode Mode, std::equality_comparable T, class U >
constexpr bool sequoia::testing::equivalence_checkable_for_semantics
 
template<class Actions , class... Args>
constexpr bool sequoia::testing::impl::has_post_comparison_action
 
template<class Actions , class... Args>
constexpr bool sequoia::testing::impl::has_post_move_action
 
template<class Actions , class... Args>
constexpr bool sequoia::testing::impl::has_post_move_assign_action
 
template<class Actions , class... Args>
constexpr bool sequoia::testing::impl::has_post_swap_action
 
template<class Actions , class... Args>
constexpr bool sequoia::testing::impl::has_post_serialization_action
 

Detailed Description

Implementation details for semantics checks that cleanly supports types which do/do not have allocators.

The general pattern in this file is of paired function templates of the form

template<test_mode Mode, class Actions, movable_comparable T, class... Args>
ret_type do_check_foo(std::string_view, test_logger<Mode>& logger, const Actions&, const T&, const T&, const Args&...);

template<test_mode Mode, class Actions, movable_comparable T>
ret_type check_foo(std::string_view description, test_logger<Mode>& logger, const sentinel<Mode>& sentry, const Actions& actions, const T& x , const T&y)
{
  return do_check_foo(description, logger, actions, x, y);
}

The idea is that the implementation of check_foo in this file is appropriate for types without allocators. As such, check_foo delegates to the instantiation of do_check_foo for which sizeof...(Args) is zero. However, do_check_foo is designed such that it can also deal with types which may allocate. As such, do_check_foo takes a template argument 'Actions'. Appropriate realizations of this type possess a bunch of constexpr static bools which indicate whether or not additional actions should be carried out.

For example, when checking the semantics of a regular type, two const references to the type must be supplied. It is a prerequisite that these instances are not equal to one another. This is always checked. However, if the type allocates, clients may prefer to utilize the allocation-checking extension supplied with sequoia. In this case, there is a constexpr flag which indicates that, after checking the prerequisite, it is further checked that

operator==

hasn't unwittingly allocated - as can happen if it accidentally captures by value rather than reference.

Thus, the general structure is

some_common_check(...);
if constexpr (Actions::some_flag)
{
  do_some_extra_check(...);
}

where the extra check is fed, amongst other things, the parameter pack args...

Therefore when checking the semantics of an allocating type, the skeleton of the function is the same as for non-allocating types. However, in the former case extra checks are folded in. This pattern ensures consistency: if the scheme is tweaked for non-allocating types, allocating types will automatically benefit. But there is enough flexbility to allow for all the extra allocation checks that allocating types require.

As such, the various check_foo functions in this header have overloads in AllocationCheckersDetails.hpp which supply the extra argument(s) for the additional actions that comprise allocation checking.

Note that check_foo / do_check_foo pairs in this file are common to both regular and move-only types. However, regular types additionally have copy semantics; the extra pieces necessary for this may be found in RegularCheckersDetails.hpp and RegularAllocationCheckerDetails.hpp

Variable Documentation

◆ checkable_against_for_semantics

template<test_mode Mode, std::equality_comparable T, class U >
constexpr bool sequoia::testing::checkable_against_for_semantics
inlineconstexpr
Initial value:

◆ equivalence_checkable_for_semantics

template<test_mode Mode, std::equality_comparable T, class U >
constexpr bool sequoia::testing::equivalence_checkable_for_semantics
inlineconstexpr
Initial value:
{
(!std::is_same_v<std::remove_cvref_t<T>, std::remove_cvref_t<U>>)
&& checkable_against<with_best_available_check_t<minimal_reporting_permitted::no>, Mode, T, U, tutor<null_advisor>>
}