{"action":"created","comment":{"url":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/comments/27445775","id":27445775,"diff_hunk":"@@ -8214,6 +8215,162 @@ unittest //12428\n     assert(s == \"abcdefghij\");\n }\n \n+\n+// generic toUpper/toLower on whole range, returns range\n+private auto toCaser(alias indexFn, uint maxIdx, alias tableFn, Range)(Range str)\n+    if (isInputRange!Range && isSomeChar!(ElementEncodingType!Range))\n+{\n+    static if (!is(Unqual!(ElementEncodingType!Range) : const(dchar)))\n+    {\n+        import std.utf.byDchar;\n+\n+        // Decode and try again\n+        return toCaser!(indexFn, maxIdx, tableFn, Range)(str.byDchar);\n+    }\n+    else\n+    {\n+        static struct toCaserImpl\n+        {\n+            this(ref Range r)\n+            {\n+                this.r = r;\n+            }\n+\n+            @property bool empty()\n+            {\n+                return !nLeft && r.empty;\n+            }\n+\n+            @property auto front() @safe\n+            {\n+                if (!nLeft)\n+                {\n+                    dchar c = r.front;\n+                    const idx = indexFn(c);\n+                    if (idx == ushort.max)\n+                    {\n+                        buf[0] = c;\n+                        nLeft = 1;\n+                    }\n+                    else if (idx < maxIdx)\n+                    {\n+                        buf[0] = tableFn(idx);\n+                        nLeft = 1;\n+                    }\n+                    else\n+                    {\n+                        auto val = tableFn(idx);\n+                        // unpack length + codepoint\n+                        nLeft = val >> 24;\n+                        assert(nLeft <= buf.length);\n+                        buf[nLeft - 1] = cast(dchar)(val & 0xFF_FFFF);\n+                        foreach (j; 1 .. nLeft)\n+                            buf[nLeft - j - 1] = tableFn(idx + j);\n+                    }\n+                }\n+                return buf[nLeft - 1];\n+            }\n+\n+            void popFront()\n+            {\n+                if (!nLeft)\n+                    front();\n+                --nLeft;\n+                if (!nLeft)\n+                    r.popFront();\n+            }\n+\n+            static if (isForwardRange!Range)\n+            {\n+                @property auto save()\n+                {\n+                    auto ret = this;\n+                    ret.r = r.save;\n+                    return ret;\n+                }\n+            }\n+\n+          private:\n+            Range r;\n+            uint nLeft;\n+            dchar[3] buf; // = void;\n+        }\n+\n+        return toCaserImpl(str);\n+    }\n+}\n+\n+/*********************\n+ * Convert input range or string to upper or lower case.\n+ *\n+ * Does not allocate memory.\n+ * Characters in UTF-8 or UTF-16 format that cannot be decoded\n+ * are treated as $(XREF utf, replacementDchar).\n+ *\n+ * Params:\n+ *      str = string or range of characters\n+ *\n+ * Returns:\n+ *      an InputRange of dchars\n+ *\n+ * See_Also:\n+ *      $(LREF toUpper), $(LREF toLower)\n+ */\n+\n+auto toLowerCase(Range)(Range str)\n+    if (isSomeString!Range ||\n+        isInputRange!Range && isSomeChar!(ElementEncodingType!Range))\n+{\n+    return toCaser!(LowerTriple)(str);\n+}\n+\n+/// ditto\n+auto toUpperCase(Range)(Range str)\n+    if (isSomeString!Range ||\n+        isInputRange!Range && isSomeChar!(ElementEncodingType!Range))\n+{\n+    return toCaser!(UpperTriple)(str);\n+}\n+\n+///\n+@safe unittest\n+{\n+    import std.array;\n+\n+    auto s = \"hEllo\".toUpperCase.array;","path":"std/uni.d","position":146,"original_position":146,"commit_id":"99356452080fbe7eb83651a6c36946b7f7e9741b","original_commit_id":"9c1cff4b5a52f93c5e8ee06f0f6d47006edff741","user":{"login":"JakobOvrum","id":155856,"avatar_url":"https://avatars.githubusercontent.com/u/155856?v=3","gravatar_id":"","url":"https://api.github.com/users/JakobOvrum","html_url":"https://github.com/JakobOvrum","followers_url":"https://api.github.com/users/JakobOvrum/followers","following_url":"https://api.github.com/users/JakobOvrum/following{/other_user}","gists_url":"https://api.github.com/users/JakobOvrum/gists{/gist_id}","starred_url":"https://api.github.com/users/JakobOvrum/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JakobOvrum/subscriptions","organizations_url":"https://api.github.com/users/JakobOvrum/orgs","repos_url":"https://api.github.com/users/JakobOvrum/repos","events_url":"https://api.github.com/users/JakobOvrum/events{/privacy}","received_events_url":"https://api.github.com/users/JakobOvrum/received_events","type":"User","site_admin":false},"body":"How about something like:\r\n```d\r\n@safe unittest\r\n{\r\n    import std.algorithm : copy;\r\n    import std.conv : text;\r\n    import std.utf : byChar;\r\n\r\n    // Construct array of converted case on the heap\r\n    auto s = \"hEllo\".toUpperCase.text; // Equivalent of using toUpper\r\n    assert(s == \"HELLO\");\r\n\r\n    // Construct array of converted case on the stack\r\n    char[16] buffer;\r\n    auto tail = \"hEllo\".toUpperCase.byChar.copy(buffer[]);\r\n    assert(buffer[0 .. $ - tail.length] == \"HELLO\");\r\n}\r\n```\r\n(I used `text` instead of `array` so everything is UTF-8)\r\n(The awkwardness of `copy` in this situation is a pattern in my code, so I'm planning on proposing a `copySome` and see what people think)","created_at":"2015-03-31T00:55:35Z","updated_at":"2015-03-31T00:55:35Z","html_url":"https://github.com/D-Programming-Language/phobos/pull/3121#discussion_r27445775","pull_request_url":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/3121","_links":{"self":{"href":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/comments/27445775"},"html":{"href":"https://github.com/D-Programming-Language/phobos/pull/3121#discussion_r27445775"},"pull_request":{"href":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/3121"}}},"pull_request":{"url":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/3121","id":32175525,"html_url":"https://github.com/D-Programming-Language/phobos/pull/3121","diff_url":"https://github.com/D-Programming-Language/phobos/pull/3121.diff","patch_url":"https://github.com/D-Programming-Language/phobos/pull/3121.patch","issue_url":"https://api.github.com/repos/D-Programming-Language/phobos/issues/3121","number":3121,"state":"open","locked":false,"title":"add std.uni.toUpperCase and toLowerCase","user":{"login":"WalterBright","id":568298,"avatar_url":"https://avatars.githubusercontent.com/u/568298?v=3","gravatar_id":"","url":"https://api.github.com/users/WalterBright","html_url":"https://github.com/WalterBright","followers_url":"https://api.github.com/users/WalterBright/followers","following_url":"https://api.github.com/users/WalterBright/following{/other_user}","gists_url":"https://api.github.com/users/WalterBright/gists{/gist_id}","starred_url":"https://api.github.com/users/WalterBright/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/WalterBright/subscriptions","organizations_url":"https://api.github.com/users/WalterBright/orgs","repos_url":"https://api.github.com/users/WalterBright/repos","events_url":"https://api.github.com/users/WalterBright/events{/privacy}","received_events_url":"https://api.github.com/users/WalterBright/received_events","type":"User","site_admin":false},"body":"Need range versions of toUpper() and toLower(). It's pretty much a copy-pasta of toUpper() and toLower(), converted to ranges.\r\n\r\n100% unittest coverage.","created_at":"2015-03-29T02:54:33Z","updated_at":"2015-03-31T00:55:35Z","closed_at":null,"merged_at":null,"merge_commit_sha":"263edec55d12a534518b7035c031211f26a479ee","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/3121/commits","review_comments_url":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/3121/comments","review_comment_url":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/comments{/number}","comments_url":"https://api.github.com/repos/D-Programming-Language/phobos/issues/3121/comments","statuses_url":"https://api.github.com/repos/D-Programming-Language/phobos/statuses/99356452080fbe7eb83651a6c36946b7f7e9741b","head":{"label":"WalterBright:toUpperCase","ref":"toUpperCase","sha":"99356452080fbe7eb83651a6c36946b7f7e9741b","user":{"login":"WalterBright","id":568298,"avatar_url":"https://avatars.githubusercontent.com/u/568298?v=3","gravatar_id":"","url":"https://api.github.com/users/WalterBright","html_url":"https://github.com/WalterBright","followers_url":"https://api.github.com/users/WalterBright/followers","following_url":"https://api.github.com/users/WalterBright/following{/other_user}","gists_url":"https://api.github.com/users/WalterBright/gists{/gist_id}","starred_url":"https://api.github.com/users/WalterBright/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/WalterBright/subscriptions","organizations_url":"https://api.github.com/users/WalterBright/orgs","repos_url":"https://api.github.com/users/WalterBright/repos","events_url":"https://api.github.com/users/WalterBright/events{/privacy}","received_events_url":"https://api.github.com/users/WalterBright/received_events","type":"User","site_admin":false},"repo":{"id":7236335,"name":"phobos","full_name":"WalterBright/phobos","owner":{"login":"WalterBright","id":568298,"avatar_url":"https://avatars.githubusercontent.com/u/568298?v=3","gravatar_id":"","url":"https://api.github.com/users/WalterBright","html_url":"https://github.com/WalterBright","followers_url":"https://api.github.com/users/WalterBright/followers","following_url":"https://api.github.com/users/WalterBright/following{/other_user}","gists_url":"https://api.github.com/users/WalterBright/gists{/gist_id}","starred_url":"https://api.github.com/users/WalterBright/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/WalterBright/subscriptions","organizations_url":"https://api.github.com/users/WalterBright/orgs","repos_url":"https://api.github.com/users/WalterBright/repos","events_url":"https://api.github.com/users/WalterBright/events{/privacy}","received_events_url":"https://api.github.com/users/WalterBright/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/WalterBright/phobos","description":"The standard library of the D programming language","fork":true,"url":"https://api.github.com/repos/WalterBright/phobos","forks_url":"https://api.github.com/repos/WalterBright/phobos/forks","keys_url":"https://api.github.com/repos/WalterBright/phobos/keys{/key_id}","collaborators_url":"https://api.github.com/repos/WalterBright/phobos/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/WalterBright/phobos/teams","hooks_url":"https://api.github.com/repos/WalterBright/phobos/hooks","issue_events_url":"https://api.github.com/repos/WalterBright/phobos/issues/events{/number}","events_url":"https://api.github.com/repos/WalterBright/phobos/events","assignees_url":"https://api.github.com/repos/WalterBright/phobos/assignees{/user}","branches_url":"https://api.github.com/repos/WalterBright/phobos/branches{/branch}","tags_url":"https://api.github.com/repos/WalterBright/phobos/tags","blobs_url":"https://api.github.com/repos/WalterBright/phobos/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/WalterBright/phobos/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/WalterBright/phobos/git/refs{/sha}","trees_url":"https://api.github.com/repos/WalterBright/phobos/git/trees{/sha}","statuses_url":"https://api.github.com/repos/WalterBright/phobos/statuses/{sha}","languages_url":"https://api.github.com/repos/WalterBright/phobos/languages","stargazers_url":"https://api.github.com/repos/WalterBright/phobos/stargazers","contributors_url":"https://api.github.com/repos/WalterBright/phobos/contributors","subscribers_url":"https://api.github.com/repos/WalterBright/phobos/subscribers","subscription_url":"https://api.github.com/repos/WalterBright/phobos/subscription","commits_url":"https://api.github.com/repos/WalterBright/phobos/commits{/sha}","git_commits_url":"https://api.github.com/repos/WalterBright/phobos/git/commits{/sha}","comments_url":"https://api.github.com/repos/WalterBright/phobos/comments{/number}","issue_comment_url":"https://api.github.com/repos/WalterBright/phobos/issues/comments{/number}","contents_url":"https://api.github.com/repos/WalterBright/phobos/contents/{+path}","compare_url":"https://api.github.com/repos/WalterBright/phobos/compare/{base}...{head}","merges_url":"https://api.github.com/repos/WalterBright/phobos/merges","archive_url":"https://api.github.com/repos/WalterBright/phobos/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/WalterBright/phobos/downloads","issues_url":"https://api.github.com/repos/WalterBright/phobos/issues{/number}","pulls_url":"https://api.github.com/repos/WalterBright/phobos/pulls{/number}","milestones_url":"https://api.github.com/repos/WalterBright/phobos/milestones{/number}","notifications_url":"https://api.github.com/repos/WalterBright/phobos/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/WalterBright/phobos/labels{/name}","releases_url":"https://api.github.com/repos/WalterBright/phobos/releases{/id}","created_at":"2012-12-19T06:55:07Z","updated_at":"2015-03-28T01:51:09Z","pushed_at":"2015-03-31T00:25:18Z","git_url":"git://github.com/WalterBright/phobos.git","ssh_url":"git@github.com:WalterBright/phobos.git","clone_url":"https://github.com/WalterBright/phobos.git","svn_url":"https://github.com/WalterBright/phobos","homepage":"dlang.org/phobos","size":40499,"stargazers_count":3,"watchers_count":3,"language":"D","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":0,"forks":2,"open_issues":0,"watchers":3,"default_branch":"master"}},"base":{"label":"D-Programming-Language:master","ref":"master","sha":"5d285a7fe1375935e53f2959bbb987f1571d5184","user":{"login":"D-Programming-Language","id":565913,"avatar_url":"https://avatars.githubusercontent.com/u/565913?v=3","gravatar_id":"","url":"https://api.github.com/users/D-Programming-Language","html_url":"https://github.com/D-Programming-Language","followers_url":"https://api.github.com/users/D-Programming-Language/followers","following_url":"https://api.github.com/users/D-Programming-Language/following{/other_user}","gists_url":"https://api.github.com/users/D-Programming-Language/gists{/gist_id}","starred_url":"https://api.github.com/users/D-Programming-Language/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/D-Programming-Language/subscriptions","organizations_url":"https://api.github.com/users/D-Programming-Language/orgs","repos_url":"https://api.github.com/users/D-Programming-Language/repos","events_url":"https://api.github.com/users/D-Programming-Language/events{/privacy}","received_events_url":"https://api.github.com/users/D-Programming-Language/received_events","type":"Organization","site_admin":false},"repo":{"id":1257084,"name":"phobos","full_name":"D-Programming-Language/phobos","owner":{"login":"D-Programming-Language","id":565913,"avatar_url":"https://avatars.githubusercontent.com/u/565913?v=3","gravatar_id":"","url":"https://api.github.com/users/D-Programming-Language","html_url":"https://github.com/D-Programming-Language","followers_url":"https://api.github.com/users/D-Programming-Language/followers","following_url":"https://api.github.com/users/D-Programming-Language/following{/other_user}","gists_url":"https://api.github.com/users/D-Programming-Language/gists{/gist_id}","starred_url":"https://api.github.com/users/D-Programming-Language/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/D-Programming-Language/subscriptions","organizations_url":"https://api.github.com/users/D-Programming-Language/orgs","repos_url":"https://api.github.com/users/D-Programming-Language/repos","events_url":"https://api.github.com/users/D-Programming-Language/events{/privacy}","received_events_url":"https://api.github.com/users/D-Programming-Language/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/D-Programming-Language/phobos","description":"The standard library of the D programming language","fork":false,"url":"https://api.github.com/repos/D-Programming-Language/phobos","forks_url":"https://api.github.com/repos/D-Programming-Language/phobos/forks","keys_url":"https://api.github.com/repos/D-Programming-Language/phobos/keys{/key_id}","collaborators_url":"https://api.github.com/repos/D-Programming-Language/phobos/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/D-Programming-Language/phobos/teams","hooks_url":"https://api.github.com/repos/D-Programming-Language/phobos/hooks","issue_events_url":"https://api.github.com/repos/D-Programming-Language/phobos/issues/events{/number}","events_url":"https://api.github.com/repos/D-Programming-Language/phobos/events","assignees_url":"https://api.github.com/repos/D-Programming-Language/phobos/assignees{/user}","branches_url":"https://api.github.com/repos/D-Programming-Language/phobos/branches{/branch}","tags_url":"https://api.github.com/repos/D-Programming-Language/phobos/tags","blobs_url":"https://api.github.com/repos/D-Programming-Language/phobos/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/D-Programming-Language/phobos/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/D-Programming-Language/phobos/git/refs{/sha}","trees_url":"https://api.github.com/repos/D-Programming-Language/phobos/git/trees{/sha}","statuses_url":"https://api.github.com/repos/D-Programming-Language/phobos/statuses/{sha}","languages_url":"https://api.github.com/repos/D-Programming-Language/phobos/languages","stargazers_url":"https://api.github.com/repos/D-Programming-Language/phobos/stargazers","contributors_url":"https://api.github.com/repos/D-Programming-Language/phobos/contributors","subscribers_url":"https://api.github.com/repos/D-Programming-Language/phobos/subscribers","subscription_url":"https://api.github.com/repos/D-Programming-Language/phobos/subscription","commits_url":"https://api.github.com/repos/D-Programming-Language/phobos/commits{/sha}","git_commits_url":"https://api.github.com/repos/D-Programming-Language/phobos/git/commits{/sha}","comments_url":"https://api.github.com/repos/D-Programming-Language/phobos/comments{/number}","issue_comment_url":"https://api.github.com/repos/D-Programming-Language/phobos/issues/comments{/number}","contents_url":"https://api.github.com/repos/D-Programming-Language/phobos/contents/{+path}","compare_url":"https://api.github.com/repos/D-Programming-Language/phobos/compare/{base}...{head}","merges_url":"https://api.github.com/repos/D-Programming-Language/phobos/merges","archive_url":"https://api.github.com/repos/D-Programming-Language/phobos/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/D-Programming-Language/phobos/downloads","issues_url":"https://api.github.com/repos/D-Programming-Language/phobos/issues{/number}","pulls_url":"https://api.github.com/repos/D-Programming-Language/phobos/pulls{/number}","milestones_url":"https://api.github.com/repos/D-Programming-Language/phobos/milestones{/number}","notifications_url":"https://api.github.com/repos/D-Programming-Language/phobos/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/D-Programming-Language/phobos/labels{/name}","releases_url":"https://api.github.com/repos/D-Programming-Language/phobos/releases{/id}","created_at":"2011-01-15T07:00:06Z","updated_at":"2015-03-30T22:59:36Z","pushed_at":"2015-03-31T00:25:19Z","git_url":"git://github.com/D-Programming-Language/phobos.git","ssh_url":"git@github.com:D-Programming-Language/phobos.git","clone_url":"https://github.com/D-Programming-Language/phobos.git","svn_url":"https://github.com/D-Programming-Language/phobos","homepage":"dlang.org/phobos","size":69977,"stargazers_count":588,"watchers_count":588,"language":"D","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":384,"mirror_url":null,"open_issues_count":54,"forks":384,"open_issues":54,"watchers":588,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/3121"},"html":{"href":"https://github.com/D-Programming-Language/phobos/pull/3121"},"issue":{"href":"https://api.github.com/repos/D-Programming-Language/phobos/issues/3121"},"comments":{"href":"https://api.github.com/repos/D-Programming-Language/phobos/issues/3121/comments"},"review_comments":{"href":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/3121/comments"},"review_comment":{"href":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/3121/commits"},"statuses":{"href":"https://api.github.com/repos/D-Programming-Language/phobos/statuses/99356452080fbe7eb83651a6c36946b7f7e9741b"}}}}