Boost logo

Boost :

Subject: Re: [boost] [local_function] any interest in a LocalFunction library?
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2010-09-15 16:56:05


On Wed, Sep 15, 2010 at 10:56 AM, Lorenzo Caminiti
<lorcaminiti_at_[hidden]> wrote:
> On Sun, Aug 22, 2010 at 11:09 AM, Lorenzo Caminiti
> <lorcaminiti_at_[hidden]> wrote:
>> Hello all,
>>
>> Is there interest in a library that implement local functions for C++?

This example compiles on both GCC and MSVC, and it shows a few
features of the library:

#include <contract/detail/local_function.hpp>
#include <iostream>
#include <algorithm>
#include <vector>

int main () {
    int offset = 5;
    std::vector<int> v;
    std::vector<int> w;

    // v = 10 20 30 40 50
    for (int i = 1; i < 6; i++) v.push_back(i * 10);
    w.resize(v.size());

    // w = ++v + 5 = 16 26 36 46 56
    CONTRACT_DETAIL_LOCAL_FUNCTION(
    (int) (inc)( (int)(i) (const bind)((&offset)) )
    ) {
        // Compiler error if const `offset` modified here by mistake.
        return ++i + offset;
    } CONTRACT_DETAIL_LOCAL_FUNCTION_END(inc)
    // `offset` is 5 for this invocation of `inc()`.
    std::transform(v.begin(), v.end(), w.begin(), inc);

    // v = ++(v + w) + 0 = 27 47 67 87 107
    CONTRACT_DETAIL_LOCAL_FUNCTION(
    (int) (inc_sum)( (int)(i) (int)(j) (bind)((inc)) )
    ) {
        return inc(i + j);
    } CONTRACT_DETAIL_LOCAL_FUNCTION_END(inc_sum)
    offset = 0; // No offset for this invocation of `inc()` via `inc_sum()`.
    std::transform(v.begin(), v.end(), w.begin(), v.begin(), inc_sum);

    for (std::vector<int>::iterator i = v.begin(); i != v.end(); ++i)
        std::cout << " " << *i;
    std::cout << std::endl;

    return 0;
}

Note:
1) The local function `inc()` is bound to the second local function
`inc_sum()` so `inc()` can be called by `inc_sum()`.
2) `offset` is bound as `const` so it cannot be modified within the
local function `inc()`.
3) However, `offset` is bound as a reference `&` so its value is 5
when `inc()` is called by the 1st `std::transform()` but then its
value is set to 0 by the enclosing function for when it is called a
second time by the `inc_sum()` as part of the 2nd `std::transform()`
call.
4) Local functions are passed as template parameters to `std::transform()`.

None of this can be done using the simpler construct:

void f() {
    struct local_function {
        static result-type body(param-list) { ... }
    };
    ...
}

--
Lorenzo

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk