{"action":"created","comment":{"url":"https://api.github.com/repos/lsst/afw/pulls/comments/87471922","pull_request_review_id":8084369,"id":87471922,"diff_hunk":"@@ -0,0 +1,261 @@\n+\n+// -*- lsst-c++ -*-\n+\n+/*\n+ * LSST Data Management System\n+ * Copyright 2008-2016  AURA/LSST.\n+ *\n+ * This product includes software developed by the\n+ * LSST Project (http://www.lsst.org/).\n+ *\n+ * This program is free software: you can redistribute it and/or modify\n+ * it under the terms of the GNU General Public License as published by\n+ * the Free Software Foundation, either version 3 of the License, or\n+ * (at your option) any later version.\n+ *\n+ * This program is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+ * GNU General Public License for more details.\n+ *\n+ * You should have received a copy of the LSST License Statement and\n+ * the GNU General Public License along with this program.  If not,\n+ * see <https://www.lsstcorp.org/LegalNotices/>.\n+ */\n+\n+ #ifndef LSST_AFW_GEOM_SPANSETFUNCTORGETTERS_H\n+ #define LSST_AFW_GEOM_SPANSETFUNCTORGETTERS_H\n+\n+#include <type_traits>\n+#include \"lsst/afw/geom/Span.h\"\n+#include \"lsst/afw/geom/Point.h\"\n+#include \"lsst/afw/image.h\"\n+#include \"lsst/pex/exceptions.h\"\n+\n+namespace lsst { namespace afw { namespace geom { namespace details {\n+\n+\n+template<typename T>\n+void variadicSetter(Span spn, T & x) {\n+    x.setSpan(spn);\n+}\n+\n+template <typename T, typename... Args>\n+void variadicSetter(Span spn, T & first, Args&... x) {\n+    variadicSetter(spn, first);\n+    variadicSetter(spn, x...);\n+}\n+\n+template<typename T>\n+void variadicChecker(Box2I box, int area, T & x) {\n+    x.checkExtents(box, area);\n+}\n+\n+template<typename T, typename... Args>\n+void variadicChecker(Box2I box, int area, T & first, Args&... x) {\n+    variadicChecker(box, area, first);\n+    variadicChecker(box, area, x...);\n+}\n+\n+template<typename T>\n+void variadicIncrement(T & x) {\n+    x.increment();\n+}\n+\n+template<typename T, typename... Args>\n+void variadicIncrement(T & first, Args&... x) {\n+    variadicIncrement(first);\n+    variadicIncrement(x...);\n+}\n+\n+template <typename T>\n+class IterGetter {\n+    /* Getter class to manage retreving values from a generic iterator\n+     */\n+ public:\n+    using type = typename std::iterator_traits<T>::value_type;\n+    explicit IterGetter(T iter): _iter(iter) {}\n+\n+    // There is no good way to check the extents of a generic iterator, so make\n+    // a no-op function to satisfy api\n+    void checkExtents(Box2I const & bbox, int area) const {}\n+\n+    void setSpan(Span const & span) {}\n+\n+    void increment() { ++_iter;}\n+\n+    typename std::iterator_traits<T>::reference get() const {return *_iter;}\n+\n+ private:\n+    T _iter;\n+};\n+\n+template <typename T>\n+class ConstantGetter {\n+    // Getter class whic takes in a constant value, and simply returns that value\n+    // for each iteration\n+ public:\n+    explicit ConstantGetter(T constant): _const(constant) {}\n+\n+    // Constants are simply repeated, so no need to check extents, make no-op\n+    // function\n+    void checkExtents(Box2I const & bbox, int area) const {}\n+\n+    void setSpan(Span const & span) {}\n+\n+    // No need to increment, make a no-op function\n+    void increment() {}\n+\n+    T get() const {return _const;}\n+ private:\n+    T _const;\n+};\n+\n+template <typename T, int N, int C>\n+class ImageNdGetter {\n+    // Getter class to manage iterating though an ndarray which is interpreted as a 2D image\n+ public:\n+    using Reference = typename ndarray::Array<T, N, C>::Reference::Reference;\n+\n+    ImageNdGetter(ndarray::Array<T, N, C> const & array, geom::Point2I xy0): _array(array), _xy0(xy0) {}\n+\n+    void checkExtents(Box2I const & bbox, int area) const {\n+        // If the bounding box lays outside the are of the image, throw an error\n+        geom::Box2I arrayBBox(_xy0, _xy0+geom::Extent2I(_array.template getSize<1>(),\n+                                                        _array.template getSize<0>()));\n+        if (!arrayBBox.contains(bbox)) {\n+            throw LSST_EXCEPT(lsst::pex::exceptions::OutOfRangeError,\n+                              \"SpanSet bounding box lands outside array\");\n+        }\n+    }\n+\n+    void setSpan(Span const & span) {\n+        auto _iterY = _array.begin() + (span.getY() - _xy0.getY());\n+        _iterX = (*_iterY).begin() + (span.getMinX() - _xy0.getX());\n+    }\n+\n+    void increment() { ++_iterX; }\n+\n+    Reference get() {\n+        return *_iterX;}\n+\n+ private:\n+    ndarray::Array<T, N, C>  _array;\n+    geom::Point2I _xy0;\n+    typename ndarray::Array<T, N, C>::Reference::Iterator _iterX;\n+};\n+\n+template <typename T>\n+class FlatNdGetter {\n+    // Getter class to manage iterating though an ndarray which is interpreted as a 2D image\n+ public:\n+    using Reference = typename ndarray::Array<T, 1, 1>::Reference;\n+\n+    explicit FlatNdGetter(ndarray::Array<T, 1, 1> const & array): _array(array) {\n+        _iter = _array.begin();\n+    }\n+\n+    void checkExtents(Box2I const & bbox, int area) {\n+        // If the area of the array is greater than the size of the array, throw an error\n+        // as the iteration dimensions will not match\n+        auto shape = _array.getShape();\n+        if (area > static_cast<int>(shape[0])) {\n+            throw LSST_EXCEPT(lsst::pex::exceptions::OutOfRangeError,\n+                              \"SpanSet has dimensionality greater than array\");\n+        }\n+    }\n+\n+    void setSpan(Span const & span) {}\n+\n+    void increment() { ++_iter; }\n+\n+    Reference get() const {\n+        return *_iter;}\n+\n+ private:\n+    ndarray::Array<T, 1, 1>  _array;\n+    typename ndarray::Array<T, 1, 1>::Iterator _iter;\n+};\n+\n+template <typename T>\n+FlatNdGetter<T> makeGetter(FlatNdGetter<T> & getter) {\n+    // This function simply passes through any FlatNdGetter passed to it\n+    return getter;\n+}\n+\n+template <typename T, int inA, int inB>\n+ImageNdGetter<T, inA, inB> makeGetter(ImageNdGetter<T, inA, inB> & getter) {\n+    // This function simply passes though any imageNdGetter passed to it\n+    return getter;\n+}\n+\n+template <typename T>\n+ImageNdGetter<T, 2, 1> makeGetter(lsst::afw::image::Image<T> & image) {","path":"include/lsst/afw/geom/SpanSetFunctorGetters.h","position":216,"original_position":193,"commit_id":"8b4851c11bb09c9cbee9d4758cc519a52dc60dfd","original_commit_id":"346bd30d76508d232cdd595d58f30bf1ee950000","user":{"login":"kfindeisen","id":8508260,"avatar_url":"https://avatars.githubusercontent.com/u/8508260?v=3","gravatar_id":"","url":"https://api.github.com/users/kfindeisen","html_url":"https://github.com/kfindeisen","followers_url":"https://api.github.com/users/kfindeisen/followers","following_url":"https://api.github.com/users/kfindeisen/following{/other_user}","gists_url":"https://api.github.com/users/kfindeisen/gists{/gist_id}","starred_url":"https://api.github.com/users/kfindeisen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kfindeisen/subscriptions","organizations_url":"https://api.github.com/users/kfindeisen/orgs","repos_url":"https://api.github.com/users/kfindeisen/repos","events_url":"https://api.github.com/users/kfindeisen/events{/privacy}","received_events_url":"https://api.github.com/users/kfindeisen/received_events","type":"User","site_admin":false},"body":"Yes, if the return type is supposed to be `ImageNdGetter<T const, 2, 1>` for the second function then this makes much more sense.","created_at":"2016-11-10T19:49:27Z","updated_at":"2016-11-10T19:49:27Z","html_url":"https://github.com/lsst/afw/pull/106#discussion_r87471922","pull_request_url":"https://api.github.com/repos/lsst/afw/pulls/106","_links":{"self":{"href":"https://api.github.com/repos/lsst/afw/pulls/comments/87471922"},"html":{"href":"https://github.com/lsst/afw/pull/106#discussion_r87471922"},"pull_request":{"href":"https://api.github.com/repos/lsst/afw/pulls/106"}}},"pull_request":{"url":"https://api.github.com/repos/lsst/afw/pulls/106","id":89724604,"html_url":"https://github.com/lsst/afw/pull/106","diff_url":"https://github.com/lsst/afw/pull/106.diff","patch_url":"https://github.com/lsst/afw/pull/106.patch","issue_url":"https://api.github.com/repos/lsst/afw/issues/106","number":106,"state":"open","locked":false,"title":"SpanSets","user":{"login":"kfindeisen","id":8508260,"avatar_url":"https://avatars.githubusercontent.com/u/8508260?v=3","gravatar_id":"","url":"https://api.github.com/users/kfindeisen","html_url":"https://github.com/kfindeisen","followers_url":"https://api.github.com/users/kfindeisen/followers","following_url":"https://api.github.com/users/kfindeisen/following{/other_user}","gists_url":"https://api.github.com/users/kfindeisen/gists{/gist_id}","starred_url":"https://api.github.com/users/kfindeisen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kfindeisen/subscriptions","organizations_url":"https://api.github.com/users/kfindeisen/orgs","repos_url":"https://api.github.com/users/kfindeisen/repos","events_url":"https://api.github.com/users/kfindeisen/events{/privacy}","received_events_url":"https://api.github.com/users/kfindeisen/received_events","type":"User","site_admin":false},"body":"Pull request for simultaneous review of [DM-2427](https://jira.lsstcorp.org/browse/DM-2427), [DM-7170](https://jira.lsstcorp.org/browse/DM-7170), and others. (@rearmstr, can you add to this list?)\n","created_at":"2016-10-17T23:55:00Z","updated_at":"2016-11-10T19:49:27Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b70fd2d19f087123461103e56b21f43d9d1a457d","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/lsst/afw/pulls/106/commits","review_comments_url":"https://api.github.com/repos/lsst/afw/pulls/106/comments","review_comment_url":"https://api.github.com/repos/lsst/afw/pulls/comments{/number}","comments_url":"https://api.github.com/repos/lsst/afw/issues/106/comments","statuses_url":"https://api.github.com/repos/lsst/afw/statuses/8b4851c11bb09c9cbee9d4758cc519a52dc60dfd","head":{"label":"lsst:tickets/DM-7170","ref":"tickets/DM-7170","sha":"8b4851c11bb09c9cbee9d4758cc519a52dc60dfd","user":{"login":"lsst","id":1134504,"avatar_url":"https://avatars.githubusercontent.com/u/1134504?v=3","gravatar_id":"","url":"https://api.github.com/users/lsst","html_url":"https://github.com/lsst","followers_url":"https://api.github.com/users/lsst/followers","following_url":"https://api.github.com/users/lsst/following{/other_user}","gists_url":"https://api.github.com/users/lsst/gists{/gist_id}","starred_url":"https://api.github.com/users/lsst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lsst/subscriptions","organizations_url":"https://api.github.com/users/lsst/orgs","repos_url":"https://api.github.com/users/lsst/repos","events_url":"https://api.github.com/users/lsst/events{/privacy}","received_events_url":"https://api.github.com/users/lsst/received_events","type":"Organization","site_admin":false},"repo":{"id":23013175,"name":"afw","full_name":"lsst/afw","owner":{"login":"lsst","id":1134504,"avatar_url":"https://avatars.githubusercontent.com/u/1134504?v=3","gravatar_id":"","url":"https://api.github.com/users/lsst","html_url":"https://github.com/lsst","followers_url":"https://api.github.com/users/lsst/followers","following_url":"https://api.github.com/users/lsst/following{/other_user}","gists_url":"https://api.github.com/users/lsst/gists{/gist_id}","starred_url":"https://api.github.com/users/lsst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lsst/subscriptions","organizations_url":"https://api.github.com/users/lsst/orgs","repos_url":"https://api.github.com/users/lsst/repos","events_url":"https://api.github.com/users/lsst/events{/privacy}","received_events_url":"https://api.github.com/users/lsst/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/lsst/afw","description":"LSST data management: astronomical framework, including images and tables","fork":false,"url":"https://api.github.com/repos/lsst/afw","forks_url":"https://api.github.com/repos/lsst/afw/forks","keys_url":"https://api.github.com/repos/lsst/afw/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lsst/afw/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lsst/afw/teams","hooks_url":"https://api.github.com/repos/lsst/afw/hooks","issue_events_url":"https://api.github.com/repos/lsst/afw/issues/events{/number}","events_url":"https://api.github.com/repos/lsst/afw/events","assignees_url":"https://api.github.com/repos/lsst/afw/assignees{/user}","branches_url":"https://api.github.com/repos/lsst/afw/branches{/branch}","tags_url":"https://api.github.com/repos/lsst/afw/tags","blobs_url":"https://api.github.com/repos/lsst/afw/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lsst/afw/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lsst/afw/git/refs{/sha}","trees_url":"https://api.github.com/repos/lsst/afw/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lsst/afw/statuses/{sha}","languages_url":"https://api.github.com/repos/lsst/afw/languages","stargazers_url":"https://api.github.com/repos/lsst/afw/stargazers","contributors_url":"https://api.github.com/repos/lsst/afw/contributors","subscribers_url":"https://api.github.com/repos/lsst/afw/subscribers","subscription_url":"https://api.github.com/repos/lsst/afw/subscription","commits_url":"https://api.github.com/repos/lsst/afw/commits{/sha}","git_commits_url":"https://api.github.com/repos/lsst/afw/git/commits{/sha}","comments_url":"https://api.github.com/repos/lsst/afw/comments{/number}","issue_comment_url":"https://api.github.com/repos/lsst/afw/issues/comments{/number}","contents_url":"https://api.github.com/repos/lsst/afw/contents/{+path}","compare_url":"https://api.github.com/repos/lsst/afw/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lsst/afw/merges","archive_url":"https://api.github.com/repos/lsst/afw/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lsst/afw/downloads","issues_url":"https://api.github.com/repos/lsst/afw/issues{/number}","pulls_url":"https://api.github.com/repos/lsst/afw/pulls{/number}","milestones_url":"https://api.github.com/repos/lsst/afw/milestones{/number}","notifications_url":"https://api.github.com/repos/lsst/afw/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lsst/afw/labels{/name}","releases_url":"https://api.github.com/repos/lsst/afw/releases{/id}","deployments_url":"https://api.github.com/repos/lsst/afw/deployments","created_at":"2014-08-16T07:37:40Z","updated_at":"2016-10-28T22:44:29Z","pushed_at":"2016-11-10T18:03:31Z","git_url":"git://github.com/lsst/afw.git","ssh_url":"git@github.com:lsst/afw.git","clone_url":"https://github.com/lsst/afw.git","svn_url":"https://github.com/lsst/afw","homepage":"http://dm.lsst.org/","size":40694,"stargazers_count":4,"watchers_count":4,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":7,"mirror_url":null,"open_issues_count":9,"forks":7,"open_issues":9,"watchers":4,"default_branch":"master"}},"base":{"label":"lsst:master","ref":"master","sha":"54aa4735e1676d87238633e48ecb7a84a8dab5b8","user":{"login":"lsst","id":1134504,"avatar_url":"https://avatars.githubusercontent.com/u/1134504?v=3","gravatar_id":"","url":"https://api.github.com/users/lsst","html_url":"https://github.com/lsst","followers_url":"https://api.github.com/users/lsst/followers","following_url":"https://api.github.com/users/lsst/following{/other_user}","gists_url":"https://api.github.com/users/lsst/gists{/gist_id}","starred_url":"https://api.github.com/users/lsst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lsst/subscriptions","organizations_url":"https://api.github.com/users/lsst/orgs","repos_url":"https://api.github.com/users/lsst/repos","events_url":"https://api.github.com/users/lsst/events{/privacy}","received_events_url":"https://api.github.com/users/lsst/received_events","type":"Organization","site_admin":false},"repo":{"id":23013175,"name":"afw","full_name":"lsst/afw","owner":{"login":"lsst","id":1134504,"avatar_url":"https://avatars.githubusercontent.com/u/1134504?v=3","gravatar_id":"","url":"https://api.github.com/users/lsst","html_url":"https://github.com/lsst","followers_url":"https://api.github.com/users/lsst/followers","following_url":"https://api.github.com/users/lsst/following{/other_user}","gists_url":"https://api.github.com/users/lsst/gists{/gist_id}","starred_url":"https://api.github.com/users/lsst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lsst/subscriptions","organizations_url":"https://api.github.com/users/lsst/orgs","repos_url":"https://api.github.com/users/lsst/repos","events_url":"https://api.github.com/users/lsst/events{/privacy}","received_events_url":"https://api.github.com/users/lsst/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/lsst/afw","description":"LSST data management: astronomical framework, including images and tables","fork":false,"url":"https://api.github.com/repos/lsst/afw","forks_url":"https://api.github.com/repos/lsst/afw/forks","keys_url":"https://api.github.com/repos/lsst/afw/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lsst/afw/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lsst/afw/teams","hooks_url":"https://api.github.com/repos/lsst/afw/hooks","issue_events_url":"https://api.github.com/repos/lsst/afw/issues/events{/number}","events_url":"https://api.github.com/repos/lsst/afw/events","assignees_url":"https://api.github.com/repos/lsst/afw/assignees{/user}","branches_url":"https://api.github.com/repos/lsst/afw/branches{/branch}","tags_url":"https://api.github.com/repos/lsst/afw/tags","blobs_url":"https://api.github.com/repos/lsst/afw/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lsst/afw/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lsst/afw/git/refs{/sha}","trees_url":"https://api.github.com/repos/lsst/afw/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lsst/afw/statuses/{sha}","languages_url":"https://api.github.com/repos/lsst/afw/languages","stargazers_url":"https://api.github.com/repos/lsst/afw/stargazers","contributors_url":"https://api.github.com/repos/lsst/afw/contributors","subscribers_url":"https://api.github.com/repos/lsst/afw/subscribers","subscription_url":"https://api.github.com/repos/lsst/afw/subscription","commits_url":"https://api.github.com/repos/lsst/afw/commits{/sha}","git_commits_url":"https://api.github.com/repos/lsst/afw/git/commits{/sha}","comments_url":"https://api.github.com/repos/lsst/afw/comments{/number}","issue_comment_url":"https://api.github.com/repos/lsst/afw/issues/comments{/number}","contents_url":"https://api.github.com/repos/lsst/afw/contents/{+path}","compare_url":"https://api.github.com/repos/lsst/afw/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lsst/afw/merges","archive_url":"https://api.github.com/repos/lsst/afw/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lsst/afw/downloads","issues_url":"https://api.github.com/repos/lsst/afw/issues{/number}","pulls_url":"https://api.github.com/repos/lsst/afw/pulls{/number}","milestones_url":"https://api.github.com/repos/lsst/afw/milestones{/number}","notifications_url":"https://api.github.com/repos/lsst/afw/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lsst/afw/labels{/name}","releases_url":"https://api.github.com/repos/lsst/afw/releases{/id}","deployments_url":"https://api.github.com/repos/lsst/afw/deployments","created_at":"2014-08-16T07:37:40Z","updated_at":"2016-10-28T22:44:29Z","pushed_at":"2016-11-10T18:03:31Z","git_url":"git://github.com/lsst/afw.git","ssh_url":"git@github.com:lsst/afw.git","clone_url":"https://github.com/lsst/afw.git","svn_url":"https://github.com/lsst/afw","homepage":"http://dm.lsst.org/","size":40694,"stargazers_count":4,"watchers_count":4,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":7,"mirror_url":null,"open_issues_count":9,"forks":7,"open_issues":9,"watchers":4,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/lsst/afw/pulls/106"},"html":{"href":"https://github.com/lsst/afw/pull/106"},"issue":{"href":"https://api.github.com/repos/lsst/afw/issues/106"},"comments":{"href":"https://api.github.com/repos/lsst/afw/issues/106/comments"},"review_comments":{"href":"https://api.github.com/repos/lsst/afw/pulls/106/comments"},"review_comment":{"href":"https://api.github.com/repos/lsst/afw/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/lsst/afw/pulls/106/commits"},"statuses":{"href":"https://api.github.com/repos/lsst/afw/statuses/8b4851c11bb09c9cbee9d4758cc519a52dc60dfd"}}}}
{"actor":{"display_login":"kfindeisen"}}