{"action":"created","comment":{"url":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/comments/33333624","id":33333624,"diff_hunk":"@@ -59,87 +48,255 @@ if (!is(Unqual!T == bool))\n         //     return result;\n         // }\n \n-        // length\n+        // Returns the number of elements in the Array.\n         @property size_t length() const\n         {\n             return _payload.length;\n         }\n \n-        // length\n+        // Sets the number of elements in the Array.\n+        // The length of the Array can never be more than the capacity.\n+        // Note: Reducing the length will remove items\n+        // from the end of the Array.\n         @property void length(size_t newLength)\n         {\n-            if (length >= newLength)\n-            {\n-                // shorten\n-                static if (hasElaborateDestructor!T)\n-                    foreach (ref e; _payload.ptr[newLength .. _payload.length])\n-                        .destroy(e);\n-\n-                _payload = _payload.ptr[0 .. newLength];\n-                return;\n-            }\n-            // enlarge\n-            auto startEmplace = length;\n-            _payload = (cast(T*) realloc(_payload.ptr,\n-                            T.sizeof * newLength))[0 .. newLength];\n-            initializeAll(_payload.ptr[startEmplace .. length]);\n+            if (newLength > capacity)\n+                capacity = newLength; // enlarge\n+            if (newLength < length)\n+                removeAt(newLength, length - newLength); // shorten\n+            _payload = _payload.ptr[0 .. newLength];\n         }\n \n-        // capacity\n+        // Returns the capacity of the Array.\n         @property size_t capacity() const\n         {\n             return _capacity;\n         }\n \n-        // reserve\n-        void reserve(size_t elements)\n+        // Set the capacity of the Array.\n+        // The capacity is the maximum size of the Array before it\n+        // must be resized.\n+        // The capacity cannot be less than the Array length.\n+        // Setting capacity to 0 will free the Array any other value\n+        // will cause a resize.\n+        @property void capacity(size_t value)\n+        {\n+            immutable isGrowing = value > capacity();\n+            \n+            if (value == 0)\n+            {\n+                // 1. Try to free the Array.\n+                if (capacity() > 0)\n+                {\n+                    assert(_payload.ptr);\n+                    static if (hasIndirections!T)\n+                        GC.removeRange(_payload.ptr);\n+                    free(_payload.ptr);\n+                    _payload = null;\n+                }\n+                else\n+                {\n+                    // Ignore, we tried to set the capacity to 0, but it was already 0.\n+                }\n+            }\n+            else\n+            {\n+                immutable sz = value * T.sizeof;\n+                immutable len = length;\n+                \n+                if (capacity() == 0)\n+                {\n+                    // 2. Allocate an Array\n+                    auto pl = enforce(cast(T*) malloc(sz))[0 .. value];\n+                    // Zero out unused capacity to prevent gc from seeing false pointers\n+                    initializeAll(pl.ptr[0 .. value]);\n+                    static if (hasIndirections!T)\n+                        GC.addRange(pl.ptr, sz);\n+                    _payload = pl.ptr[0 .. len];\n+                }\n+                else\n+                {\n+                    // 3. Resize the Array\n+                    static if (hasIndirections!T)       // should use hasPointers instead\n+                    {\n+                        /* Because of the transactional nature of this\n+                         * relative to the garbage collector, ensure no\n+                         * threading bugs by using malloc/copy/free rather\n+                         * than realloc.\n+                         */\n+                        auto pl = enforce(cast(T*) malloc(sz))[0 .. value];\n+                        // copy old data over to new Array\n+                        memcpy(pl.ptr, _payload.ptr, T.sizeof * len);\n+                        \n+                        // Zero out unused capacity to prevent gc from seeing false pointers\n+                        if (isGrowing)\n+                            initializeAll(pl.ptr[len .. value]);\n+                        \n+                        GC.addRange(pl.ptr, sz);\n+                        GC.removeRange(_payload.ptr);\n+                        free(_payload.ptr);\n+                        _payload = pl.ptr[0 .. len];\n+                    }\n+                    else\n+                    {\n+                        /* These can't have pointers, so no need to zero\n+                         * unused region\n+                         */\n+                        auto pl = enforce(cast(T*) realloc(_payload.ptr, sz))[0 .. value];\n+                        if (isGrowing)\n+                            initializeAll(pl.ptr[len .. value]);\n+                        _payload = pl.ptr[0 .. len];\n+                    }\n+                }\n+            }\n+            \n+            _capacity = value;\n+        }\n+        \n+        // Requests the Array to change its capacity to at least howMuch.\n+        // If howMuch is greater than the current capacity the Array is\n+        // resized, otherwise no action is taken and the capactity\n+        // remains unchanged.\n+        void reserve(size_t howMuch)\n+        {\n+            immutable cap = capacity;\n+            \n+            if (howMuch > cap)\n+            {\n+                size_t sz = (cap == 0) ? 4 : (cap * 3 / 2); // grow rule 1/3\n+                if (sz < howMuch)\n+                    sz = howMuch;\n+                capacity = sz;\n+                \n+                assert(capacity > length && _payload.ptr);\n+            }\n+        }\n+        \n+        // Requests the Array to reduce its capacity to howMuch.\n+        // If the Array length is greater than howMuch the length\n+        // will be truncated, before the capacity is reduced.\n+        void shrink(size_t howMuch)\n         {\n-            if (elements <= capacity) return;\n-            immutable sz = elements * T.sizeof;\n-            static if (hasIndirections!T)       // should use hasPointers instead\n+            immutable cap = capacity;\n+            \n+            if (howMuch < cap)\n+            {\n+                length = cap;\n+                capacity = cap;\n+                \n+                assert(capacity == length && _payload.ptr);\n+            }\n+        }\n+        \n+        // Remove one entry at the specified index.\n+        // An entry will be destroyed it appropriately.\n+        \n+        // Complexity: $(BIGOH n)\n+        void removeAt(size_t index)\n+        {\n+            enforce(index >= 0 && index <= length);\n+            static if (is(T == struct) && hasElaborateDestructor!T)","path":"std/container/array.d","position":204,"original_position":204,"commit_id":"c2f03a8149be9395c8df5b87845a56a25e31a961","original_commit_id":"c2f03a8149be9395c8df5b87845a56a25e31a961","user":{"login":"monarchdodra","id":1911406,"avatar_url":"https://avatars.githubusercontent.com/u/1911406?v=3","gravatar_id":"","url":"https://api.github.com/users/monarchdodra","html_url":"https://github.com/monarchdodra","followers_url":"https://api.github.com/users/monarchdodra/followers","following_url":"https://api.github.com/users/monarchdodra/following{/other_user}","gists_url":"https://api.github.com/users/monarchdodra/gists{/gist_id}","starred_url":"https://api.github.com/users/monarchdodra/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/monarchdodra/subscriptions","organizations_url":"https://api.github.com/users/monarchdodra/orgs","repos_url":"https://api.github.com/users/monarchdodra/repos","events_url":"https://api.github.com/users/monarchdodra/events{/privacy}","received_events_url":"https://api.github.com/users/monarchdodra/received_events","type":"User","site_admin":false},"body":"Don't check for struct. Other types, such as static arrays, can also have destructors. Also, enums of structs I think don't match for struct unless you do `BaseType!T`. Long story short, just trust `hasElaborateDestructor` to know what it's doing. This is a compile time static if, so it's \"free\".","created_at":"2015-06-26T07:14:59Z","updated_at":"2015-06-26T07:14:59Z","html_url":"https://github.com/D-Programming-Language/phobos/pull/2441#discussion_r33333624","pull_request_url":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/2441","_links":{"self":{"href":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/comments/33333624"},"html":{"href":"https://github.com/D-Programming-Language/phobos/pull/2441#discussion_r33333624"},"pull_request":{"href":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/2441"}}},"pull_request":{"url":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/2441","id":20015995,"html_url":"https://github.com/D-Programming-Language/phobos/pull/2441","diff_url":"https://github.com/D-Programming-Language/phobos/pull/2441.diff","patch_url":"https://github.com/D-Programming-Language/phobos/pull/2441.patch","issue_url":"https://api.github.com/repos/D-Programming-Language/phobos/issues/2441","number":2441,"state":"open","locked":false,"title":"Refactor container/array.d","user":{"login":"damianday","id":1334173,"avatar_url":"https://avatars.githubusercontent.com/u/1334173?v=3","gravatar_id":"","url":"https://api.github.com/users/damianday","html_url":"https://github.com/damianday","followers_url":"https://api.github.com/users/damianday/followers","following_url":"https://api.github.com/users/damianday/following{/other_user}","gists_url":"https://api.github.com/users/damianday/gists{/gist_id}","starred_url":"https://api.github.com/users/damianday/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/damianday/subscriptions","organizations_url":"https://api.github.com/users/damianday/orgs","repos_url":"https://api.github.com/users/damianday/repos","events_url":"https://api.github.com/users/damianday/events{/privacy}","received_events_url":"https://api.github.com/users/damianday/received_events","type":"User","site_admin":false},"body":"Main changes:\r\nRemoveAt, InsertAt - Private API.\r\nCapacity - It can now shrink and enlarge - however there is no public API to enlarge.\r\n\r\nMost internals re-factored to use RemoveAt, InsertAt - avoids a lot\r\nof duplication and ensures proper clean-up when objects were being removed.\r\n\r\nFix issue:\r\n13619\r\n13642","created_at":"2014-08-19T23:12:43Z","updated_at":"2015-06-26T07:14:59Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2bd275260ce0eb97f430324d6501d8dda705b112","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/2441/commits","review_comments_url":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/2441/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/2441/comments","statuses_url":"https://api.github.com/repos/D-Programming-Language/phobos/statuses/c2f03a8149be9395c8df5b87845a56a25e31a961","head":{"label":"damianday:container_array","ref":"container_array","sha":"c2f03a8149be9395c8df5b87845a56a25e31a961","user":{"login":"damianday","id":1334173,"avatar_url":"https://avatars.githubusercontent.com/u/1334173?v=3","gravatar_id":"","url":"https://api.github.com/users/damianday","html_url":"https://github.com/damianday","followers_url":"https://api.github.com/users/damianday/followers","following_url":"https://api.github.com/users/damianday/following{/other_user}","gists_url":"https://api.github.com/users/damianday/gists{/gist_id}","starred_url":"https://api.github.com/users/damianday/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/damianday/subscriptions","organizations_url":"https://api.github.com/users/damianday/orgs","repos_url":"https://api.github.com/users/damianday/repos","events_url":"https://api.github.com/users/damianday/events{/privacy}","received_events_url":"https://api.github.com/users/damianday/received_events","type":"User","site_admin":false},"repo":{"id":19087482,"name":"phobos","full_name":"damianday/phobos","owner":{"login":"damianday","id":1334173,"avatar_url":"https://avatars.githubusercontent.com/u/1334173?v=3","gravatar_id":"","url":"https://api.github.com/users/damianday","html_url":"https://github.com/damianday","followers_url":"https://api.github.com/users/damianday/followers","following_url":"https://api.github.com/users/damianday/following{/other_user}","gists_url":"https://api.github.com/users/damianday/gists{/gist_id}","starred_url":"https://api.github.com/users/damianday/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/damianday/subscriptions","organizations_url":"https://api.github.com/users/damianday/orgs","repos_url":"https://api.github.com/users/damianday/repos","events_url":"https://api.github.com/users/damianday/events{/privacy}","received_events_url":"https://api.github.com/users/damianday/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/damianday/phobos","description":"The standard library of the D programming language","fork":true,"url":"https://api.github.com/repos/damianday/phobos","forks_url":"https://api.github.com/repos/damianday/phobos/forks","keys_url":"https://api.github.com/repos/damianday/phobos/keys{/key_id}","collaborators_url":"https://api.github.com/repos/damianday/phobos/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/damianday/phobos/teams","hooks_url":"https://api.github.com/repos/damianday/phobos/hooks","issue_events_url":"https://api.github.com/repos/damianday/phobos/issues/events{/number}","events_url":"https://api.github.com/repos/damianday/phobos/events","assignees_url":"https://api.github.com/repos/damianday/phobos/assignees{/user}","branches_url":"https://api.github.com/repos/damianday/phobos/branches{/branch}","tags_url":"https://api.github.com/repos/damianday/phobos/tags","blobs_url":"https://api.github.com/repos/damianday/phobos/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/damianday/phobos/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/damianday/phobos/git/refs{/sha}","trees_url":"https://api.github.com/repos/damianday/phobos/git/trees{/sha}","statuses_url":"https://api.github.com/repos/damianday/phobos/statuses/{sha}","languages_url":"https://api.github.com/repos/damianday/phobos/languages","stargazers_url":"https://api.github.com/repos/damianday/phobos/stargazers","contributors_url":"https://api.github.com/repos/damianday/phobos/contributors","subscribers_url":"https://api.github.com/repos/damianday/phobos/subscribers","subscription_url":"https://api.github.com/repos/damianday/phobos/subscription","commits_url":"https://api.github.com/repos/damianday/phobos/commits{/sha}","git_commits_url":"https://api.github.com/repos/damianday/phobos/git/commits{/sha}","comments_url":"https://api.github.com/repos/damianday/phobos/comments{/number}","issue_comment_url":"https://api.github.com/repos/damianday/phobos/issues/comments{/number}","contents_url":"https://api.github.com/repos/damianday/phobos/contents/{+path}","compare_url":"https://api.github.com/repos/damianday/phobos/compare/{base}...{head}","merges_url":"https://api.github.com/repos/damianday/phobos/merges","archive_url":"https://api.github.com/repos/damianday/phobos/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/damianday/phobos/downloads","issues_url":"https://api.github.com/repos/damianday/phobos/issues{/number}","pulls_url":"https://api.github.com/repos/damianday/phobos/pulls{/number}","milestones_url":"https://api.github.com/repos/damianday/phobos/milestones{/number}","notifications_url":"https://api.github.com/repos/damianday/phobos/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/damianday/phobos/labels{/name}","releases_url":"https://api.github.com/repos/damianday/phobos/releases{/id}","created_at":"2014-04-23T22:15:27Z","updated_at":"2014-06-30T14:49:17Z","pushed_at":"2014-10-25T14:55:55Z","git_url":"git://github.com/damianday/phobos.git","ssh_url":"git@github.com:damianday/phobos.git","clone_url":"https://github.com/damianday/phobos.git","svn_url":"https://github.com/damianday/phobos","homepage":"dlang.org/phobos","size":31136,"stargazers_count":0,"watchers_count":0,"language":"D","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"D-Programming-Language:master","ref":"master","sha":"4c9132dc246ee2af15339343688abf8ef7940bf7","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-06-17T14:55:53Z","pushed_at":"2015-06-26T01:12:06Z","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":87240,"stargazers_count":609,"watchers_count":609,"language":"D","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":409,"mirror_url":null,"open_issues_count":79,"forks":409,"open_issues":79,"watchers":609,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/2441"},"html":{"href":"https://github.com/D-Programming-Language/phobos/pull/2441"},"issue":{"href":"https://api.github.com/repos/D-Programming-Language/phobos/issues/2441"},"comments":{"href":"https://api.github.com/repos/D-Programming-Language/phobos/issues/2441/comments"},"review_comments":{"href":"https://api.github.com/repos/D-Programming-Language/phobos/pulls/2441/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/2441/commits"},"statuses":{"href":"https://api.github.com/repos/D-Programming-Language/phobos/statuses/c2f03a8149be9395c8df5b87845a56a25e31a961"}}}}