Thread overview
Read Once then reset/init value?
Oct 29, 2019
Robert M. Münch
Oct 29, 2019
Simen Kjærås
Oct 30, 2019
Jacob Carlborg
Oct 30, 2019
Simen Kjærås
Nov 04, 2019
Robert M. Münch
October 29, 2019
I quite often have the pattern where a value should be read just once and after this reset itself. The idea is to avoid that others read the value by accident and get an older state, instead they get an "invalid/reset" value.

Is there a library function that can mimic such a behaviour?

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster

October 29, 2019
On Tuesday, 29 October 2019 at 22:24:20 UTC, Robert M. Münch wrote:
> I quite often have the pattern where a value should be read just once and after this reset itself. The idea is to avoid that others read the value by accident and get an older state, instead they get an "invalid/reset" value.
>
> Is there a library function that can mimic such a behaviour?

Something like this?

T readOnce(T)(ref T value) {
    auto tmp = value;
    value = T.init;
    return tmp;
} unittest {
    int i = 3;
    assert(i.readOnce == 3);
    assert(i == 0);
}

If so, no, there is no library function for it, but feel free to use the above. You may very well have to change T.init to something more fitting for your use case, of course.

If this is not what you need, feel free to explain further, as I'm not sure I understood you correctly. :)

--
  Simen
October 30, 2019
On 2019-10-30 00:28, Simen Kjærås wrote:

> Something like this?
> 
> T readOnce(T)(ref T value) {
>      auto tmp = value;
>      value = T.init;
>      return tmp;
> } unittest {
>      int i = 3;
>      assert(i.readOnce == 3);
>      assert(i == 0);
> }

Perhaps better to encapsulate it in a struct to avoid someone accessing the value directly.

-- 
/Jacob Carlborg
October 30, 2019
On Wednesday, 30 October 2019 at 11:53:42 UTC, Jacob Carlborg wrote:
> On 2019-10-30 00:28, Simen Kjærås wrote:
>
>> Something like this?
>> 
>> T readOnce(T)(ref T value) {
>>      auto tmp = value;
>>      value = T.init;
>>      return tmp;
>> } unittest {
>>      int i = 3;
>>      assert(i.readOnce == 3);
>>      assert(i == 0);
>> }
>
> Perhaps better to encapsulate it in a struct to avoid someone accessing the value directly.

Quite possibly, but the post was somewhat low on details, and encapsulating it like that does put certain limits on how it can be used, so it's not necessarily the best idea.

FWIW, here's one possible way to do it with a struct:

struct Readonce(T, T defaultValue = T.init) {
    private T value;

    alias get this;

    T get() {
        auto tmp = value;
        value = defaultValue;
        return tmp;
    }

    void get(T newValue) {
        value = newValue;
    }

    this(T newValue) {
        value = newValue;
    }
}

unittest {
    Readonce!(int, -1) a = 3;
    assert(a == 3);
    assert(a == -1);

    a = 3;
    assert(a == 3);
    assert(a == -1);
}

--
  Simen
November 04, 2019
On 2019-10-29 23:28:35 +0000, Simen Kjærås said:

> On Tuesday, 29 October 2019 at 22:24:20 UTC, Robert M. Münch wrote:
>> I quite often have the pattern where a value should be read just once and after this reset itself. The idea is to avoid that others read the value by accident and get an older state, instead they get an "invalid/reset" value.
>> 
>> Is there a library function that can mimic such a behaviour?
> 
> Something like this?
> 
> T readOnce(T)(ref T value) {
>      auto tmp = value;
>      value = T.init;
>      return tmp;
> } unittest {
>      int i = 3;
>      assert(i.readOnce == 3);
>      assert(i == 0);
> }
> 
> If so, no, there is no library function for it, but feel free to use the above. You may very well have to change T.init to something more fitting for your use case, of course.

Hi, that looks very good. I forgot about the UFCS possibility. That's very good because it works on basic types too. Thanks :-)

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster