# GotW #101: Preconditions, Part 2 (Difficulty: 7/10)

This special Guru of the Week series focuses on contracts. We covered some basics of preconditions in GotW #100. This time, let’s see how we can use preconditions in some practical examples…

## JG Question

1. Consider these functions, expanded from an article by Andrzej Krzemieński: 

```// Adapted from 

auto is_in_values (int val, int min, int max)
-> bool; // true iff val is in the values [min, max]

auto is_in_container (int val, int idx_min, int idx_max)
-> bool; // true iff container[i]==val for some i in [idx_min, idx_max]

template <typename T, typename Iter>
auto is_in_range (T val, Iter first, Iter last)
-> bool; // true iff *i==val for some i in [first,last)
```

How many ways could a caller of each function get the arguments wrong, but that would silently compile without error? Name as many different ways as you can.

## Guru Questions

2. Show how can you improve the function declarations in Question 1 by:

(a) just grouping parameters, using a struct with public variables

(b) just using an encapsulated class, using a class with private variables (an abstraction with its own invariant)

(c) just using post-C++20 contract preconditions (not yet valid C++, but something like the syntax in )

In each case, how many of the possible kinds of mistakes for each function can the approach prevent?

3. Consider these three examples, where each shows expressing a boolean condition either as a function precondition or as an encapsulated invariant inside a new type:

```// (a) A vector that is sorted

template <typename T>
void f( vector<T> const& v ) [[pre( is_sorted(v) )]] ;

template <typename T>
void f( sorted<vector<T>> const& v );

// (b) A vector that is not empty

template <typename T>
void f( vector<T> const& v ) [[pre( !v.empty() )]] ;

template <typename T>
void f( not_empty<vector<T>> const& v );

// (c) A pointer that is not null

void f( int* p ) [[pre( p != nullptr )]] ;

void f( not_null<int*> p );
```

In each of these cases, which way is better? Explain your answer.

# Notes

 A. Krzemieński. “Contracts, preconditions and invariants” (Andrzej’s C++ blog, December 2020).

 G. Dos Reis, J. D. Garcia, J. Lakos, A. Meredith, N. Myers, and B. Stroustrup. “P0542: Support for contract based programming in C++” (WG21 paper, June 2018). Subsequent EWG discussion favored changing “expects” to “pre” and “ensures” to “post,” and to keep it as legal compilable (if unenforced) C++20 for this article I also modified the syntax from : to ( ). That’s not a statement of preference, it’s just so the examples can compile today to make them easier to check.