explicit
A set of small tools that allow you to state your intentions more explicitly in the interfaces.
out_param
Tool A tool for indicating function output parameters in call sites:
void clear(out_param<std::string&> s) // output parameter in function declaration
{
s.get().clear();
}
std::string s {"text"};
clear(out(s)); // in function invokation
For more, see here.
tagged_bool
Tool An alternative to type bool
in function arguments. It allows to associate a name with the boolean type. No nasty implicit converisons from/to int
, double
, or pointers. Different instantiations of tagged_bool
are not interconvertible:
class EngineStartedTag_; // never defined
class CrewReadyTag_; // never defined
using EngineStarted = tagged_bool<EngineStartedTag_>; // one boolean type
using CrewReady = tagged_bool<CrewReadyTag_>; // another boolean type
void set_status(EngineStarted started, CrewReady ready); // function declaration
set_status(EngineStarted{true}, CrewReady{true}); // function invokation
For more, see here.
only_when
Tool A tool for disabling some unwanted implicit conversions to types present in your function signatures. For instance, you may want your function to take a filesystem::path
but not allow an implicit conversion from std::string
:
using only_path = only_when<filesystem::path, is_a_non_string>; // you define type trait is_a_non_string
void process(only_path p); // function declaration
process(path); // ok
process(string); // error
For more, see here.
only_int
Tool An alternative to type int
in function arguments. It binds to int
s and int proxies but not to double
:
void scale(only_int i); // declaration
scale(2); // ok
scale(2.5); // error
For more, see here.
lvalue_ref
Tool This allows the constructor parameters to bind to lvalues, but not to rvalues:
struct Processor
{
Big const& _big;
explicit Processor(lvalue_ref<const Big> b) : _big(b) {}
};
const Big b {};
Processor p {b}; // ok
Processor q {Big{}}; // error (temporary)
For more, see here.
not_null
Tool This allows to indicate in function interface that a passed pointer is assumed never to be null:
void process(not_null<i*> p); // function declaration
int i = 0;
process(&i); // error: no implicit conversion to not_null
process(as_not_null(&i)); // ok: explicit adjustment
For more, see here.
installation
It is a C++11 header-only library.
All library components are defined in namespace ak_toolkit::xplicit
. However,
including header <ak_toolkit/namespace_xpl>
introduces a shorter alias xpl
.
Using xpl
is shorter, but risks clashes in case a different library also
uses short xpl
for some other purpose. If that happens, you have to go with the
longer but safer version.
License
Distributed under the Boost Software License, Version 1.0.
Acknowledgements
The idea of the generalized only_when
was proposed by Vicente J. Botet Escriba. Tomasz Kamiński suggested the support for std::reference_wrapper
in rvalue_ref
.