{"action":"created","issue":{"url":"https://api.github.com/repos/brycelelbach/wg21_p1135_cpp20_synchronization_library/issues/12","repository_url":"https://api.github.com/repos/brycelelbach/wg21_p1135_cpp20_synchronization_library","labels_url":"https://api.github.com/repos/brycelelbach/wg21_p1135_cpp20_synchronization_library/issues/12/labels{/name}","comments_url":"https://api.github.com/repos/brycelelbach/wg21_p1135_cpp20_synchronization_library/issues/12/comments","events_url":"https://api.github.com/repos/brycelelbach/wg21_p1135_cpp20_synchronization_library/issues/12/events","html_url":"https://github.com/brycelelbach/wg21_p1135_cpp20_synchronization_library/issues/12","id":538086043,"node_id":"MDU6SXNzdWU1MzgwODYwNDM=","number":12,"title":"binary_semaphore::max() requirements","user":{"login":"hadrielk","id":3319094,"node_id":"MDQ6VXNlcjMzMTkwOTQ=","avatar_url":"https://avatars1.githubusercontent.com/u/3319094?v=4","gravatar_id":"","url":"https://api.github.com/users/hadrielk","html_url":"https://github.com/hadrielk","followers_url":"https://api.github.com/users/hadrielk/followers","following_url":"https://api.github.com/users/hadrielk/following{/other_user}","gists_url":"https://api.github.com/users/hadrielk/gists{/gist_id}","starred_url":"https://api.github.com/users/hadrielk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hadrielk/subscriptions","organizations_url":"https://api.github.com/users/hadrielk/orgs","repos_url":"https://api.github.com/users/hadrielk/repos","events_url":"https://api.github.com/users/hadrielk/events{/privacy}","received_events_url":"https://api.github.com/users/hadrielk/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2019-12-15T18:14:11Z","updated_at":"2019-12-15T20:52:58Z","closed_at":null,"author_association":"NONE","body":"Hi,\r\nSince `binary_semaphore` is an alias for `counting_semaphore<1>`, there are some weird implications that I wanted to confirm were intentional (or at least not undesired).\r\n\r\n`counting_semaphore::max()` says this:\r\n```\r\nReturns: The maximum value of counter. This value is greater than or equal to least_max_value.\r\n```\r\nwhich means a `binary_semaphore::max()` can theoretically return a value greater than `1`.\r\n\r\nIn the original proposal [P0514R4](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0514r4.pdf), however, it implied the max value was required to be `1`.  (I think?)\r\n\r\nThe only reason this matters, and why I'm asking, is whether a user can _always_ safely do this to initialize the `binary_semaphore` via the constructor:\r\n```\r\nstd::binary_semaphore sem{std::binary_semaphore::max()};\r\n```\r\n\r\nPer the current wording of [N4842](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4842.pdf), doing that would be valid, even if `binary_semaphore:max()` yields `2`. But presumably that would break the semantics of `binary_semaphore`.\r\n\r\nAnd the same issue applies for `binary_semaphore::release(binary_semaphore::max())`, although in practice presumably users would never provide an argument for `binary_semaphore::release()` since the default argument value is `1` anyway.\r\n\r\n----\r\n\r\nThe reason this stuff matters, I think, is that users could write generic template classes/functions that only deal with `counting_semaphore<N>` by using `max()` generically, without having to specialize for `binary_semaphore`/`counting_semaphore<1>`... if it were safe to do so.\r\n\r\n----\r\n\r\nAs an aside, arguably this `max()` issue applies to `counting_semaphore`s in general - it seems odd to me that `max()` could return a value greater than the template param value. The user _specified_ the max value using the template param, and that's what they should always see; the fact that internally it might be larger should be a hidden detail, no? Otherwise using `max()` would lead to exceeding the specified template value.\r\n\r\nHaving said that, I recognize the non-type template param is specifically named `least_max_value`, and thus provides the hint it's only a _minimum_ max value. So if I want to say: \"up to 4 concurrent accessors are allowed\", I can't. I can only say: \"at least 4 or more concurrent accessors are allowed\". Is that the intention?\r\n"},"comment":{"url":"https://api.github.com/repos/brycelelbach/wg21_p1135_cpp20_synchronization_library/issues/comments/565845750","html_url":"https://github.com/brycelelbach/wg21_p1135_cpp20_synchronization_library/issues/12#issuecomment-565845750","issue_url":"https://api.github.com/repos/brycelelbach/wg21_p1135_cpp20_synchronization_library/issues/12","id":565845750,"node_id":"MDEyOklzc3VlQ29tbWVudDU2NTg0NTc1MA==","user":{"login":"hadrielk","id":3319094,"node_id":"MDQ6VXNlcjMzMTkwOTQ=","avatar_url":"https://avatars1.githubusercontent.com/u/3319094?v=4","gravatar_id":"","url":"https://api.github.com/users/hadrielk","html_url":"https://github.com/hadrielk","followers_url":"https://api.github.com/users/hadrielk/followers","following_url":"https://api.github.com/users/hadrielk/following{/other_user}","gists_url":"https://api.github.com/users/hadrielk/gists{/gist_id}","starred_url":"https://api.github.com/users/hadrielk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hadrielk/subscriptions","organizations_url":"https://api.github.com/users/hadrielk/orgs","repos_url":"https://api.github.com/users/hadrielk/repos","events_url":"https://api.github.com/users/hadrielk/events{/privacy}","received_events_url":"https://api.github.com/users/hadrielk/received_events","type":"User","site_admin":false},"created_at":"2019-12-15T20:52:58Z","updated_at":"2019-12-15T20:52:58Z","author_association":"NONE","body":"Oh, I'm not asking for a change at all - just clarification of intent. I'm creating the pages for it for [cppreference.com](https://en.cppreference.com), and just wanted to understand the design choices/intent.\r\n\r\nIn my mind I was thinking of `max()` as a convenience constant for users of the class, to be usable without having to know what an actual type's `least_max_value` was. (for example so one could do `using semaphore = std::counting_semaphore<4>;` in some common/library header, and users of it could do `semapahore::max()` for initialization without having to know `4`) But really this is a very minor thing, and I have no idea if anyone would ever want to do such a thing, and it's easily avoidable using an `integral_constant` or some such anyway. I was more just slightly surprised/confused, really.\r\n\r\nThanks for the reply!"}}
{"actor":{"display_login":"hadrielk"}}