basic_facade_builder::add_convention
basic_facade_builder::add_direct_convention
basic_facade_builder::add_indirect_convention
template <class D, class... Os> requires(/* see below */)
using add_convention = add_indirect_convention<D, Os...>;
template <class D, class... Os> requires(/* see below */)
using add_indirect_convention = basic_facade_builder</* see below */>;
template <class D, class... Os> requires(/* see below */)
using add_direct_convention = basic_facade_builder</* see below */>;
The alias templates add_convention, add_indirect_convention, and add_direct_convention of basic_facade_builder<Cs, Rs, MaxSize, MaxAlign, Copyability, Relocatability, Destructibility> add convention types to the template parameters. The expression inside requires is equivalent to sizeof...(Os) > 0u and each type in Os meets the ProOverload requirements. Let F be a facade type,
add_conventionis equivalent toadd_indirect_convention.add_indirect_conventionmerges an implementation-defined convention typeICintoCs, where:IC::is_directisfalse.typename IC::dispatch_typeisD.typename IC::overload_typesis a tuple-like type of distinct types inOs.typename IC::template accessor<F>istypename D::template accessor<proxy_indirect_accessor<F>, D,substituted-overload<Os, F>...>if applicable.
add_direct_conventionmerges an implementation-defined convention typeICintoCs, where:IC::is_directistrue.typename IC::dispatch_typeisD.typename IC::overload_typesis a tuple-like type of distinct types inOs.typename IC::template accessor<F>istypename D::template accessor<proxy<F>, D,substituted-overload<Os, F>...>if applicable.
When Cs already contains a convention type IC2 where IC2::is_direct == IC::is_direct && std::is_same_v<typename IC2::dispatch_type, typename IC::dispatch_type> is true, Os merges with typename IC2::overload_types and removes duplicates, and std::tuple_size_v<Cs> shall not change.
Notes
Adding duplicated combinations of some dispatch type and overload type is well-defined (either directly via add_convention, add_indirect_convention, add_direct_convention, or indirectly via add_facade), and does not have side-effects to build at either compile-time or runtime.
Example
#include <iostream>
#include <memory>
#include <string>
#include <proxy/proxy.h>
PRO_DEF_FREE_DISPATCH(FreeToString, std::to_string, ToString);
struct BasicStringable : pro::facade_builder //
::add_convention<FreeToString, std::string() const> //
::build {};
struct Stringable : pro::facade_builder //
::add_facade<BasicStringable> //
::support_copy<pro::constraint_level::nontrivial> //
::add_direct_convention<pro::conversion_dispatch,
pro::proxy<BasicStringable>() &&> //
::build {};
int main() {
pro::proxy<Stringable> p1 = std::make_shared<int>(123);
pro::proxy<Stringable> p2 = p1;
pro::proxy<BasicStringable> p3 =
static_cast<pro::proxy<BasicStringable>>(std::move(p2));
pro::proxy<BasicStringable> p4 = std::move(p3);
// pro::proxy<BasicStringable> p5 = p4; // Won't compile
std::cout << ToString(*p4) << "\n"; // Prints "123"
std::cout << std::boolalpha << p3.has_value() << "\n"; // Prints "false"
}