December 05, 2017
On Tuesday, 5 December 2017 at 17:25:57 UTC, Steven Schveighoffer wrote:
[...]
> struct LowerCaseFirst(R) // if(isSomeString!R)
> {
>    R src;
>    bool notFirst; // terrible name, but I want default false
>    dchar front() {
>       import std.uni: toLower;
>       return notFirst ? src.front : src.front.toLower;
>    }
>    void popFront() { notFirst = true; src.popFront; }
>    bool empty() { return src.empty; }
> }
>
> auto lowerCaseFirst(R)(R r)
> {
>    return LowerCaseFirst!R(r);
> }
>
> Warning: it ain't going to be fast. Auto-decoding everywhere.

But one cannot use the return value of lowerCaseFirst as argument for foo(string). Only the use as argument to writeln seems to work. Also I had to put

    import std.range.primitives : front, popFront, empty;

outside the struct otherwise the compiler complains about missing front, popFront and empty for type string.
December 05, 2017
On 12/05/2017 11:41 AM, kdevel wrote:
> On Tuesday, 5 December 2017 at 17:25:57 UTC, Steven Schveighoffer wrote:

> But one cannot use the return value of lowerCaseFirst as argument for foo(string). Only the use as argument to writeln seems to work.

That's how ranges work. LowerCaseFirst produces dchar elements one at a time. An easy way of getting a string out of it is calling std.conv.text, which converts all those dchars to a series of UTF-8 chars.

Note, .text below is an expensive call because it allocates a new string. You may want to cache its result first if you need the result more than once:

    auto lowered = lowerCaseFirst("HELLO").text;
    foo(lowered);

This works:

import std.range;

struct LowerCaseFirst(R) // if(isSomeString!R)
{
   R src;
   bool notFirst; // terrible name, but I want default false
   dchar front() {
      import std.uni: toLower;
      return notFirst ? src.front : src.front.toLower;
   }
   void popFront() { notFirst = true; src.popFront; }
   bool empty() { return src.empty; }
}

auto lowerCaseFirst(R)(R r)
{
   return LowerCaseFirst!R(r);
}

void foo(string s) {
    import std.stdio;
    writefln("good old string: %s", s);
}

void main() {
    import std.conv;
    foo(lowerCaseFirst("HELLO").text);
}

Ali
December 05, 2017
On 12/5/17 2:41 PM, kdevel wrote:
> On Tuesday, 5 December 2017 at 17:25:57 UTC, Steven Schveighoffer wrote:
> [...]
>> struct LowerCaseFirst(R) // if(isSomeString!R)
>> {
>>    R src;
>>    bool notFirst; // terrible name, but I want default false
>>    dchar front() {
>>       import std.uni: toLower;
>>       return notFirst ? src.front : src.front.toLower;
>>    }
>>    void popFront() { notFirst = true; src.popFront; }
>>    bool empty() { return src.empty; }
>> }
>>
>> auto lowerCaseFirst(R)(R r)
>> {
>>    return LowerCaseFirst!R(r);
>> }
>>
>> Warning: it ain't going to be fast. Auto-decoding everywhere.
> 
> But one cannot use the return value of lowerCaseFirst as argument for foo(string).

Define foo as:

foo(R)(R r) if (isInputRange!R && isSomeChar!(ElementType!R))

Then it can take any range of char types.

> Only the use as argument to writeln seems to work. Also I had to put
> 
>      import std.range.primitives : front, popFront, empty;
> 
> outside the struct otherwise the compiler complains about missing front, popFront and empty for type string.

Yeah, it wasn't a complete example. These are the extensions to arrays that allow them to work as ranges.

-Steve
December 06, 2017
On Tuesday, 5 December 2017 at 13:31:17 UTC, Marc wrote:
> Does D have a native function to capitalize only the first letter of the word? (I'm asking that so I might avoid reinvent the wheel, which I did sometimes in D)

// ----------------
module test;

import std.stdio;

void main()
{
    string myString = "heLlo WoRlD!";
    writeln( HereItIs(myString) );
}


string HereItIs(string someString)
{
    import std.uni : toLower;
    import std.ascii : toUpper;

    return (someString.ptr[0].toUpper ~  someString[1..$].toLower);
}
// ------------------

1 2
Next ›   Last »