{"action":"created","comment":{"url":"https://api.github.com/repos/ericniebler/stl2/pulls/comments/47038406","id":47038406,"diff_hunk":"@@ -0,0 +1,230 @@\n+%!TEX root = stl2-ts.tex\n+\\infannex{sentrework}{Iterator Design Rationale}\n+\n+\\pnum\n+The design of the iterator and sentinel concepts in this document differs\n+substantially from the design presented in N4560. In short, N4560 had separate\n+``weak'' and ``strong'' variants of \\tcode{Iterator}, \\tcode{InputIterator}, and\n+\\tcode{OutputIterator}; in the current design the ``strong''\n+(\\tcode{EqualityComparable}~(\\ref{concepts.lib.compare.equalitycomparable})) variants have been removed and the \\tcode{Weak}\n+prefix has been elided from the names of the ``weak'' variants. This rationale\n+justifies the change and clarifies that it does not diminish the expressive\n+power of iterator / sentinel pairs and ranges.\n+\n+\\rSec1[sentrework.problem]{Problem statement}\n+\n+\\pnum\n+Consider a threshold sentinel \\tcode{S} with state consisting of a single\n+integer \\tcode{bound}. When compared for equality with an iterator, this\n+sentinel's \\tcode{==} returns \\tcode{true} if and only if the iterator denotes\n+a value greater than or equal to \\tcode{bound}. \\tcode{S} seems like a useful\n+tool, and it's simple enough to be described completely in a couple of\n+sentences. One would expect it to be expressible within the sentinel model of\n+N4560. Given an array of integers:\n+\\begin{codeblock}\n+  int i[] = {2,1,3};\n+\\end{codeblock}\n+By any sensible definition of ``the same range,'' \\range{i+1}{S\\{2\\}} and\n+\\range{i+1}{S\\{3\\}} (where \\tcode{S\\{n\\}} is a threshold sentinel with\n+\\tcode{bound} of \\tcode{n}) denote the same range. \\tcode{*(i+1) == 1} is less\n+than both bounds (\\tcode{2} and \\tcode{3}), and \\tcode{*(i+2) == 3} is greater\n+than or equal to both bounds, so both ranges have length of one and denote only\n+the single integer with value \\tcode{1}.\n+\n+\\pnum\n+N4560 requires iterators and their sentinels to satisfy the cross-type\n+\\tcode{EqualityComparable<T,U>()} concept~(\\ref{concepts.lib.compare.equalitycomparable}).\n+\\tcode{EqualityComparable} effectively requires the values of the two\n+participant types \\tcode{T} and \\tcode{U} to be put into correspondence: if two\n+objects \\tcode{t1} and \\tcode{t2} of one type both compare equal to some value\n+of the other type, those objects must be equal. The meaning of ``be equal'' is\n+very clearly defined in the Ranges TS by the semantics of equality preserving\n+expressions~(\\ref{concepts.lib.general.equality}). If \\tcode{t1} and \\tcode{t2}\n+are equal, the result of evaluating any expression required to be equality\n+preserving must be the same for both \\tcode{t1} and \\tcode{t2}. Informally,\n+the correspondence enforced by \\tcode{EqualityComparable} requires values of the\n+participant types to both represent the same abstract entities as personified by\n+their common type.\n+\n+\\pnum\n+Returning to the example above, the consequences of the\n+\\tcode{EqualityComparable} requirement are clear: since \\tcode{i+2 == S\\{2\\}}\n+and \\tcode{i+2 == S\\{3\\}}, \\tcode{S\\{2\\}} and \\tcode{S\\{3\\}} must be equal. If\n+they are equal, then the ranges \\range{i+0}{S\\{2\\}} and \\range{i+0}{S\\{3\\}} must\n+also denote the same range due to the equality preservation of the expressions\n+involved. This is, however, not the case since \\tcode{*(i+0) == 2} is greater\n+than or equal to \\tcode{2} but not greater than or equal to \\tcode{3}.\n+\\tcode{EqualityComparable<S,int*>()} and therefore \\tcode{Sentinel<S,int*>()}\n+are not satisfied; \\tcode{S} is not a valid sentinel for \\tcode{int*}.\n+\n+\\pnum\n+Clearly there is a large class of useful sentinels that the N4560 model does\n+not admit: stateful sentinels which might compare equal to the same iterator\n+when they have differing state. N4560 constrains iterators and sentinels to\n+both represent the abstract notion of ``position,'' which is not a good fit\n+for stateful sentinels.\n+\n+\\rSec1[sentrework.approach]{Fixing the problem}\n+\n+\\pnum\n+It seems odd to claim that the sentinel semantics are broken when there are two\n+working implementations of the TS~(\\cite{range-v3}, \\cite{cmcstl2}) that haven't\n+had any issues due to this semantic inconsistency. The clear implication is that\n+the semantics of the N4560 model are not an exact match for the requirements of\n+the algorithms. The semantics are likely overconstrained and could be relaxed\n+without losing the properties the algorithms need to support equational\n+reasoning.\n+\n+\\rSec2[sentrework.approach.alg]{Look at the Algorithms}\n+\n+\\pnum\n+As is often the case, a problem in the semantics is best fixed by examining\n+the algorithms and determining what behaviors they require to ensure their\n+postconditions. The properties the algorithms require for sentinels are (where\n+\\tcode{s} denotes a sentinel value and \\tcode{i} an iterator value):\n+\\begin{itemize}\n+\\item \\tcode{i == s}, \\tcode{s == i}, \\tcode{i != s}, and \\tcode{s != i} are\n+      equality-preserving expressions with the same definition space.\n+\\item Symmetry: \\tcode{bool(i == s) == bool(s == i)} and\n+      \\tcode{bool(i != s) == bool(s != i)}.\n+\\item Complement: \\tcode{bool(i != s) == !bool(i == s)}.\n+\\item \\tcode{i == s} is well-defined when \\range{i}{s} denotes a range.\n+\\end{itemize}\n+\n+\\pnum\n+The first three properties aren't specific to iterators and sentinels; they are\n+general characteristics of the operators \\tcode{==} and \\tcode{!=} that are\n+intuitively expected to hold whenever they are defined. As such, the\n+\\tcode{EqualityComparable} concepts should require them to hold and this\n+particular set of properties can then be presented as a relaxation of\n+\\tcode{EqualityComparable<T,U>()}. The current design does exactly that,\n+defining the concept\n+\\tcode{Bike\\-shed\\-Equal\\-ity\\-Comp\\-arable}~(\\ref{concepts.lib.compare.equalitycomparable})\n+with exactly the specified semantic requirements, and reformulating both the\n+single and cross-type variants of \\tcode{EqualityComparable} as refinements\n+thereof.\n+\n+\\pnum\n+Notably, nothing in this list of properties requires comparison of sentinels\n+with other sentinels -- it's not a useful feature for generic code. The\n+requirement for equality comparison of sentinels in N4560 is a checkbox feature\n+to enable satisfaction of cross-type \\tcode{EqualityComparable}. Absent the\n+\\tcode{EqualityComparable} requirement, nothing in the design requires equality\n+comparison for sentinels. It's nonsensical to require sentinels to have\n+\\tcode{Regular} types if \\tcode{==} is never required to be valid or useful,\n+they should be \\tcode{Semiregular}.\n+\n+\\pnum\n+The list of properties also does not require that iterator types be\n+\\tcode{EqualityComparable} to participate in the \\tcode{Sentinel} relationship.\n+Just as removing the cross-type \\tcode{EqualityComparable} requirement\n+makes it unnecessary for sentinels to be \\tcode{EqualityComparable} with\n+other sentinels, it also removes the necessity for the iterator type to be\n+\\tcode{EqualityComparable}. In N4560 terms, \\tcode{Sentinel} should be a\n+relationship between a \\tcode{WeakIterator} type that denotes an element of a\n+range and a \\tcode{Semiregular} type that represents an end-of-range calculation\n+as a predicate over \\tcode{WeakIterator} values embodied in the form of the\n+\\tcode{==} operator, i.e.:\n+\\begin{codeblock}\n+template <class S, class I>\n+concept bool Sentinel() {\n+  return Semiregular<S>() && WeakIterator<I>() &&\n+    BikeshedEqualityComparable<S, I>();\n+}\n+\\end{codeblock}\n+a non-weak iterator is capable of both denoting an element and the end of a\n+range. In other words, a ``strong'' iterator is a type that is simultaneously a\n+weak iterator and a sentinel for that weak iterator:\n+\\begin{codeblock}\n+template <class I>\n+concept bool Iterator() {\n+  return Sentinel<I, I>() &&\n+    EqualityComparable<I>(); // Keep the semantic property that == means\n+                             // substitutable in equality-preserving expressions\n+}\n+\\end{codeblock}\n+\n+\\rSec1[sentrework.ram]{Ramifications}\n+\n+\\pnum\n+Correcting the inconsistency in the \\tcode{Sentinel} semantics creates a class\n+of ``weak'' ranges -- ranges with \\tcode{WeakInput} or \\tcode{WeakOutput}\n+iterator types -- that the algorithms do not admit. It would appear that\n+algorithms that accept input (output) ranges should possibly be relaxed to\n+accept weak input (weak output) ranges instead. How would doing so constrain\n+the implementations of the algorithms? Do weak ranges have less expressive power?\n+\n+\\rSec2[sentrework.ram.singlepass]{Single-pass Algorithms}\n+\n+\\pnum\n+Algorithms that accept input or output iterators necessarily perform at most one\n+pass over the range of elements those iterators reference, N4560's weak input and\n+weak output iterators are consistent with those single-pass semantics. The\n+distinction is obviously support for equality comparison. How do algorithms use","path":"sentrework.tex","position":163,"original_position":163,"commit_id":"ff7ccc296a796533743296029f98f932cd75cd3d","original_commit_id":"ff7ccc296a796533743296029f98f932cd75cd3d","user":{"login":"CaseyCarter","id":456873,"avatar_url":"https://avatars.githubusercontent.com/u/456873?v=3","gravatar_id":"","url":"https://api.github.com/users/CaseyCarter","html_url":"https://github.com/CaseyCarter","followers_url":"https://api.github.com/users/CaseyCarter/followers","following_url":"https://api.github.com/users/CaseyCarter/following{/other_user}","gists_url":"https://api.github.com/users/CaseyCarter/gists{/gist_id}","starred_url":"https://api.github.com/users/CaseyCarter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CaseyCarter/subscriptions","organizations_url":"https://api.github.com/users/CaseyCarter/orgs","repos_url":"https://api.github.com/users/CaseyCarter/repos","events_url":"https://api.github.com/users/CaseyCarter/events{/privacy}","received_events_url":"https://api.github.com/users/CaseyCarter/received_events","type":"User","site_admin":false},"body":"\"distinction is..support\" is complete, the \"obviously\" is out of place. \"The sole distinction is support for equality comparison.\" is more direct and reads better.","created_at":"2015-12-09T00:50:30Z","updated_at":"2015-12-09T00:50:30Z","html_url":"https://github.com/ericniebler/stl2/pull/153#discussion_r47038406","pull_request_url":"https://api.github.com/repos/ericniebler/stl2/pulls/153","_links":{"self":{"href":"https://api.github.com/repos/ericniebler/stl2/pulls/comments/47038406"},"html":{"href":"https://github.com/ericniebler/stl2/pull/153#discussion_r47038406"},"pull_request":{"href":"https://api.github.com/repos/ericniebler/stl2/pulls/153"}}},"pull_request":{"url":"https://api.github.com/repos/ericniebler/stl2/pulls/153","id":51161302,"html_url":"https://github.com/ericniebler/stl2/pull/153","diff_url":"https://github.com/ericniebler/stl2/pull/153.diff","patch_url":"https://github.com/ericniebler/stl2/pull/153.patch","issue_url":"https://api.github.com/repos/ericniebler/stl2/issues/153","number":153,"state":"open","locked":false,"title":"Sharpen semantics of Iterators and Sentinels:","user":{"login":"CaseyCarter","id":456873,"avatar_url":"https://avatars.githubusercontent.com/u/456873?v=3","gravatar_id":"","url":"https://api.github.com/users/CaseyCarter","html_url":"https://github.com/CaseyCarter","followers_url":"https://api.github.com/users/CaseyCarter/followers","following_url":"https://api.github.com/users/CaseyCarter/following{/other_user}","gists_url":"https://api.github.com/users/CaseyCarter/gists{/gist_id}","starred_url":"https://api.github.com/users/CaseyCarter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CaseyCarter/subscriptions","organizations_url":"https://api.github.com/users/CaseyCarter/orgs","repos_url":"https://api.github.com/users/CaseyCarter/repos","events_url":"https://api.github.com/users/CaseyCarter/events{/privacy}","received_events_url":"https://api.github.com/users/CaseyCarter/received_events","type":"User","site_admin":false},"body":"* Specify the required definition space of comparison operations on Iterators and Sentinels.\r\n* Rename SizedIteratorRange to SizedSentinel, factor out SizedIterator. Locate both concepts immediately after Iterator and Sentinel, respectively. (The section [iteratorranges] no longer exists.)\r\n* CommonSizedIteratorRange has *not* been renamed.\r\n* Rename disable_sized_range to disable_sized, make it a variable template, and relocate to [iterators.sizediterator]. disable_sized serves as an opt out trait for both SizedIterator and SizedRange (and indirectly SizedSentinel, since it requires its iterator type to satisfy SizedIterator).\r\n* Respecify distance and advance in light of the updated iterator/sentinel/sized semantics.\r\n\r\nCloses caseycarter/stl2#13.\r\nCloses caseycarter/stl2#20.\r\nTouches on ericneibler/stl2#88.\r\nCloses ericniebler/stl2#107.\r\nCloses ericniebler/stl2#131.\r\n\r\nMy approach for `distance` and `advance` was to specify a distinct overload for every syntactically distinguishable precondition. Yes, that results in a dozen or so total overloads of `advance` - not \"counting\" the overload for `counted_iterator` - which is verging on the ridiculous. I think that more overloads with simpler specifications of requirements and effects result in a more readable spec than would fewer overloads with \"Requires: A or B or C\"...\"Effects: If A then X, otherwise if B then Y, otherwise if C then Z\". Opinions will of course vary.","created_at":"2015-11-18T23:55:30Z","updated_at":"2015-12-09T00:50:31Z","closed_at":null,"merged_at":null,"merge_commit_sha":"bba311a7c40f2fc735fab146e7d4e73a8809ee05","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/ericniebler/stl2/pulls/153/commits","review_comments_url":"https://api.github.com/repos/ericniebler/stl2/pulls/153/comments","review_comment_url":"https://api.github.com/repos/ericniebler/stl2/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ericniebler/stl2/issues/153/comments","statuses_url":"https://api.github.com/repos/ericniebler/stl2/statuses/ff7ccc296a796533743296029f98f932cd75cd3d","head":{"label":"CaseyCarter:advance","ref":"advance","sha":"ff7ccc296a796533743296029f98f932cd75cd3d","user":{"login":"CaseyCarter","id":456873,"avatar_url":"https://avatars.githubusercontent.com/u/456873?v=3","gravatar_id":"","url":"https://api.github.com/users/CaseyCarter","html_url":"https://github.com/CaseyCarter","followers_url":"https://api.github.com/users/CaseyCarter/followers","following_url":"https://api.github.com/users/CaseyCarter/following{/other_user}","gists_url":"https://api.github.com/users/CaseyCarter/gists{/gist_id}","starred_url":"https://api.github.com/users/CaseyCarter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CaseyCarter/subscriptions","organizations_url":"https://api.github.com/users/CaseyCarter/orgs","repos_url":"https://api.github.com/users/CaseyCarter/repos","events_url":"https://api.github.com/users/CaseyCarter/events{/privacy}","received_events_url":"https://api.github.com/users/CaseyCarter/received_events","type":"User","site_admin":false},"repo":{"id":36177743,"name":"stl2","full_name":"CaseyCarter/stl2","owner":{"login":"CaseyCarter","id":456873,"avatar_url":"https://avatars.githubusercontent.com/u/456873?v=3","gravatar_id":"","url":"https://api.github.com/users/CaseyCarter","html_url":"https://github.com/CaseyCarter","followers_url":"https://api.github.com/users/CaseyCarter/followers","following_url":"https://api.github.com/users/CaseyCarter/following{/other_user}","gists_url":"https://api.github.com/users/CaseyCarter/gists{/gist_id}","starred_url":"https://api.github.com/users/CaseyCarter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CaseyCarter/subscriptions","organizations_url":"https://api.github.com/users/CaseyCarter/orgs","repos_url":"https://api.github.com/users/CaseyCarter/repos","events_url":"https://api.github.com/users/CaseyCarter/events{/privacy}","received_events_url":"https://api.github.com/users/CaseyCarter/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/CaseyCarter/stl2","description":"","fork":true,"url":"https://api.github.com/repos/CaseyCarter/stl2","forks_url":"https://api.github.com/repos/CaseyCarter/stl2/forks","keys_url":"https://api.github.com/repos/CaseyCarter/stl2/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CaseyCarter/stl2/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CaseyCarter/stl2/teams","hooks_url":"https://api.github.com/repos/CaseyCarter/stl2/hooks","issue_events_url":"https://api.github.com/repos/CaseyCarter/stl2/issues/events{/number}","events_url":"https://api.github.com/repos/CaseyCarter/stl2/events","assignees_url":"https://api.github.com/repos/CaseyCarter/stl2/assignees{/user}","branches_url":"https://api.github.com/repos/CaseyCarter/stl2/branches{/branch}","tags_url":"https://api.github.com/repos/CaseyCarter/stl2/tags","blobs_url":"https://api.github.com/repos/CaseyCarter/stl2/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CaseyCarter/stl2/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CaseyCarter/stl2/git/refs{/sha}","trees_url":"https://api.github.com/repos/CaseyCarter/stl2/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CaseyCarter/stl2/statuses/{sha}","languages_url":"https://api.github.com/repos/CaseyCarter/stl2/languages","stargazers_url":"https://api.github.com/repos/CaseyCarter/stl2/stargazers","contributors_url":"https://api.github.com/repos/CaseyCarter/stl2/contributors","subscribers_url":"https://api.github.com/repos/CaseyCarter/stl2/subscribers","subscription_url":"https://api.github.com/repos/CaseyCarter/stl2/subscription","commits_url":"https://api.github.com/repos/CaseyCarter/stl2/commits{/sha}","git_commits_url":"https://api.github.com/repos/CaseyCarter/stl2/git/commits{/sha}","comments_url":"https://api.github.com/repos/CaseyCarter/stl2/comments{/number}","issue_comment_url":"https://api.github.com/repos/CaseyCarter/stl2/issues/comments{/number}","contents_url":"https://api.github.com/repos/CaseyCarter/stl2/contents/{+path}","compare_url":"https://api.github.com/repos/CaseyCarter/stl2/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CaseyCarter/stl2/merges","archive_url":"https://api.github.com/repos/CaseyCarter/stl2/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CaseyCarter/stl2/downloads","issues_url":"https://api.github.com/repos/CaseyCarter/stl2/issues{/number}","pulls_url":"https://api.github.com/repos/CaseyCarter/stl2/pulls{/number}","milestones_url":"https://api.github.com/repos/CaseyCarter/stl2/milestones{/number}","notifications_url":"https://api.github.com/repos/CaseyCarter/stl2/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CaseyCarter/stl2/labels{/name}","releases_url":"https://api.github.com/repos/CaseyCarter/stl2/releases{/id}","created_at":"2015-05-24T15:06:54Z","updated_at":"2015-07-21T12:34:07Z","pushed_at":"2015-12-08T23:29:14Z","git_url":"git://github.com/CaseyCarter/stl2.git","ssh_url":"git@github.com:CaseyCarter/stl2.git","clone_url":"https://github.com/CaseyCarter/stl2.git","svn_url":"https://github.com/CaseyCarter/stl2","homepage":null,"size":44189,"stargazers_count":2,"watchers_count":2,"language":"TeX","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":8,"forks":0,"open_issues":8,"watchers":2,"default_branch":"master"}},"base":{"label":"ericniebler:master","ref":"master","sha":"0b474c1daf56e2a6b8e518d33f0b20d1147925b8","user":{"login":"ericniebler","id":225757,"avatar_url":"https://avatars.githubusercontent.com/u/225757?v=3","gravatar_id":"","url":"https://api.github.com/users/ericniebler","html_url":"https://github.com/ericniebler","followers_url":"https://api.github.com/users/ericniebler/followers","following_url":"https://api.github.com/users/ericniebler/following{/other_user}","gists_url":"https://api.github.com/users/ericniebler/gists{/gist_id}","starred_url":"https://api.github.com/users/ericniebler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ericniebler/subscriptions","organizations_url":"https://api.github.com/users/ericniebler/orgs","repos_url":"https://api.github.com/users/ericniebler/repos","events_url":"https://api.github.com/users/ericniebler/events{/privacy}","received_events_url":"https://api.github.com/users/ericniebler/received_events","type":"User","site_admin":false},"repo":{"id":26772882,"name":"stl2","full_name":"ericniebler/stl2","owner":{"login":"ericniebler","id":225757,"avatar_url":"https://avatars.githubusercontent.com/u/225757?v=3","gravatar_id":"","url":"https://api.github.com/users/ericniebler","html_url":"https://github.com/ericniebler","followers_url":"https://api.github.com/users/ericniebler/followers","following_url":"https://api.github.com/users/ericniebler/following{/other_user}","gists_url":"https://api.github.com/users/ericniebler/gists{/gist_id}","starred_url":"https://api.github.com/users/ericniebler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ericniebler/subscriptions","organizations_url":"https://api.github.com/users/ericniebler/orgs","repos_url":"https://api.github.com/users/ericniebler/repos","events_url":"https://api.github.com/users/ericniebler/events{/privacy}","received_events_url":"https://api.github.com/users/ericniebler/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ericniebler/stl2","description":"LaTeX and Markdown source for the Ranges TS/STL2 and associated proposals","fork":false,"url":"https://api.github.com/repos/ericniebler/stl2","forks_url":"https://api.github.com/repos/ericniebler/stl2/forks","keys_url":"https://api.github.com/repos/ericniebler/stl2/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ericniebler/stl2/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ericniebler/stl2/teams","hooks_url":"https://api.github.com/repos/ericniebler/stl2/hooks","issue_events_url":"https://api.github.com/repos/ericniebler/stl2/issues/events{/number}","events_url":"https://api.github.com/repos/ericniebler/stl2/events","assignees_url":"https://api.github.com/repos/ericniebler/stl2/assignees{/user}","branches_url":"https://api.github.com/repos/ericniebler/stl2/branches{/branch}","tags_url":"https://api.github.com/repos/ericniebler/stl2/tags","blobs_url":"https://api.github.com/repos/ericniebler/stl2/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ericniebler/stl2/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ericniebler/stl2/git/refs{/sha}","trees_url":"https://api.github.com/repos/ericniebler/stl2/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ericniebler/stl2/statuses/{sha}","languages_url":"https://api.github.com/repos/ericniebler/stl2/languages","stargazers_url":"https://api.github.com/repos/ericniebler/stl2/stargazers","contributors_url":"https://api.github.com/repos/ericniebler/stl2/contributors","subscribers_url":"https://api.github.com/repos/ericniebler/stl2/subscribers","subscription_url":"https://api.github.com/repos/ericniebler/stl2/subscription","commits_url":"https://api.github.com/repos/ericniebler/stl2/commits{/sha}","git_commits_url":"https://api.github.com/repos/ericniebler/stl2/git/commits{/sha}","comments_url":"https://api.github.com/repos/ericniebler/stl2/comments{/number}","issue_comment_url":"https://api.github.com/repos/ericniebler/stl2/issues/comments{/number}","contents_url":"https://api.github.com/repos/ericniebler/stl2/contents/{+path}","compare_url":"https://api.github.com/repos/ericniebler/stl2/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ericniebler/stl2/merges","archive_url":"https://api.github.com/repos/ericniebler/stl2/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ericniebler/stl2/downloads","issues_url":"https://api.github.com/repos/ericniebler/stl2/issues{/number}","pulls_url":"https://api.github.com/repos/ericniebler/stl2/pulls{/number}","milestones_url":"https://api.github.com/repos/ericniebler/stl2/milestones{/number}","notifications_url":"https://api.github.com/repos/ericniebler/stl2/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ericniebler/stl2/labels{/name}","releases_url":"https://api.github.com/repos/ericniebler/stl2/releases{/id}","created_at":"2014-11-17T19:19:15Z","updated_at":"2015-10-08T20:13:22Z","pushed_at":"2015-12-08T23:29:14Z","git_url":"git://github.com/ericniebler/stl2.git","ssh_url":"git@github.com:ericniebler/stl2.git","clone_url":"https://github.com/ericniebler/stl2.git","svn_url":"https://github.com/ericniebler/stl2","homepage":"","size":40513,"stargazers_count":23,"watchers_count":23,"language":"TeX","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":6,"mirror_url":null,"open_issues_count":28,"forks":6,"open_issues":28,"watchers":23,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ericniebler/stl2/pulls/153"},"html":{"href":"https://github.com/ericniebler/stl2/pull/153"},"issue":{"href":"https://api.github.com/repos/ericniebler/stl2/issues/153"},"comments":{"href":"https://api.github.com/repos/ericniebler/stl2/issues/153/comments"},"review_comments":{"href":"https://api.github.com/repos/ericniebler/stl2/pulls/153/comments"},"review_comment":{"href":"https://api.github.com/repos/ericniebler/stl2/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ericniebler/stl2/pulls/153/commits"},"statuses":{"href":"https://api.github.com/repos/ericniebler/stl2/statuses/ff7ccc296a796533743296029f98f932cd75cd3d"}}}}