Boost logo

Boost :

Subject: Re: [boost] [Concepts] Definition. Was [GSoC] [Boost.Hana] Formal review request
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2014-08-16 12:12:51

On 15 Aug 2014 at 12:42, Robert Ramey wrote:

> You might try putting these propositions to the test by seeing
> what happens when one tries to explicitly specify type requirements
> to AFIO - assuming this has yet to be done. It would be interesting
> to know if this weren't possible.

Ah, this isn't needed in AFIO. And I suppose it is useful to explain

AFIO is pure batch, so all APIs consume and emit std::vector<T> where
T is an API-specific type. The mapping looks like this (subset):

vector<async_io_op> <= dir(), rmdir(), file(), rmfile(), symlink(),
rmsymlink() <= vector<async_path_op_req>

vector<async_io_op> <= read(), write() <=

  vector<future<pair<vector<directory_entry>, bool>>>,
> <= enumerate() <= vector<async_enumerate_op_req>

In other words, inputs are very strongly typed, and the input
containers do considerable static and dynamic sanity checking. For
example, read() and write() both accept vectors of
async_data_op_req<T>, and async_data_op_req<T> will implicitly
construct itself from any of:

1. boost::asio::const_buffer and mutable_buffer, or std::array or
std::vector of const_buffer and mutable_buffer.
2. const T * and T * if also supplied with a size_t length and T is
3. const std::array<T, N> and non-const if T is trivial.
4. const std::basic_string<C, T, A> and non-const.
5. const std::vector<T, A> and non-const if T is trivial.
6. const void * and T * if also supplied with a size_t length in

const semantics are adhered to, so passing a const input to read()
raises a compile-time error. However write() will accept both const
and mutable inputs.

The reasons for the concreteness is because AFIO keeps a stable ABI
which keeps platform-specific stuff in non-header code (it defaults
to all header only though), and that means concrete types for the ABI
stability. Because of that hard concrete type requirement, genericity
at the next layer of API higher is tightly constrained, so I have
made those constraints specific by a specifically defined input type
constraint class per API which will handle the adaptation where it is
possible, and won't compile otherwise. This produces very useful
error messages because of the per-API input type checking - you can
instantly see what is wrong and why because the compiler will print
out all the constructor overloads which didn't match and why.

I don't claim that this is a panacea - it does demand a lot of work
from the programmer, and it is intentionally ungeneric and I have no
idea how well it would scale. However, it concentrates all the
brittleness into a single location and it generates very useful error
messages. I'm certainly pleased with it to date. It should form an
excellent basis for integration into the monadic continuations
framework, which is what it was designed from the beginning to do.


ned Productions Limited Consulting

Boost list run by bdawes at, gregod at, cpdaniel at, john at