Skip to content

Commit

Permalink
feat(formattedRead): add overloads to return a tuple with the read va…
Browse files Browse the repository at this point in the history
…lues

Signed-off-by: João Lourenço <jlourenco5691@gmail.com>
  • Loading branch information
iK4tsu committed Nov 24, 2024
1 parent 7bcb86b commit 20d987c
Showing 1 changed file with 67 additions and 0 deletions.
67 changes: 67 additions & 0 deletions std/format/read.d
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ module std.format.read;

import std.format.spec : FormatSpec;
import std.format.internal.read;
import std.meta : allSatisfy;
import std.traits : isSomeString, isType;

/**
Expand Down Expand Up @@ -692,6 +693,72 @@ if (!isType!fmt && isSomeString!(typeof(fmt)))
assert(aa2 == ["hello":1, "world":2]);
}

/**
Reads an input range according to a format string and returns a tuple with the
read values.
Format specifiers with format character $(B 'd'), $(B 'u') and $(B
'c') can take a $(B '*') parameter for skipping values.
The second version of `formattedRead` takes the format string as
template argument. In this case, it is checked for consistency at
compile-time.
Params:
Args = a variadic list of types of the arguments
*/
template formattedRead(Args...)
if (Args.length && allSatisfy!(isType, Args))
{
import std.typecons : Flag, Tuple, Yes;

/**
Params:
r = an $(REF_ALTTEXT input range, isInputRange, std, range, primitives),
where the formatted input is read from
fmt = a $(MREF_ALTTEXT format string, std,format)
Range = the type of the input range `r`
Char = the character type used for `fmt`
Returns:
A Tuple!Args with the elements filled. If the input range `r` ends early,
the missing arguments will be default initialized.
Throws:
A $(REF_ALTTEXT FormatException, FormatException, std, format)
if reading did not succeed.
*/
Tuple!Args formattedRead(Range, Char)(auto ref Range r, const(Char)[] fmt)
{
import core.lifetime : forward;
import std.exception : enforce;
import std.format : FormatException;

Tuple!Args args;
const numArgsFilled = .formattedRead(forward!r, fmt, args.expand);
enforce!FormatException(numArgsFilled == Args.length);
return args;
}
}

/// ditto
template formattedRead(alias fmt, Args...)
if (!isType!fmt && isSomeString!(typeof(fmt)) && Args.length && allSatisfy!(isType, Args))
{
import std.typecons : Flag, Tuple, Yes;
Tuple!Args formattedRead(Range)(auto ref Range r)
{
import core.lifetime : forward;
import std.exception : enforce;
import std.format : FormatException;

Tuple!Args args;
const numArgsFilled = .formattedRead!fmt(forward!r, args.expand);
enforce!FormatException(numArgsFilled == Args.length);
return args;
}
}

/**
Reads a value from the given _input range and converts it according to a
format specifier.
Expand Down

0 comments on commit 20d987c

Please sign in to comment.