{"id":16752363,"url":"https://github.com/wumpf/optionalscopedobject","last_synced_at":"2026-08-13T20:32:15.423Z","repository":{"id":146737137,"uuid":"57440789","full_name":"Wumpf/optionalscopedobject","owner":"Wumpf","description":"Optional scoped objects for modern C++","archived":false,"fork":false,"pushed_at":"2016-04-30T13:28:46.000Z","size":11,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-13T08:50:53.441Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Wumpf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-04-30T12:24:47.000Z","updated_at":"2016-04-30T12:46:54.000Z","dependencies_parsed_at":null,"dependency_job_id":"d863b311-a47c-451f-ba81-b9cbb7caec16","html_url":"https://github.com/Wumpf/optionalscopedobject","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Wumpf/optionalscopedobject","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wumpf%2Foptionalscopedobject","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wumpf%2Foptionalscopedobject/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wumpf%2Foptionalscopedobject/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wumpf%2Foptionalscopedobject/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Wumpf","download_url":"https://codeload.github.com/Wumpf/optionalscopedobject/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wumpf%2Foptionalscopedobject/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":36619914,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-08-06T04:43:03.162Z","status":"online","status_checked_at":"2026-08-13T02:00:06.325Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-13T02:46:46.410Z","updated_at":"2026-08-13T20:32:15.406Z","avatar_url":"https://github.com/Wumpf.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# optionalscopedobject\n\nRecently I ran into a weird situation where a threading lock was either passed, or not (since locking might or might not be appropriate in a given situation).\nSince I am always very concerned about other people adding early out return statements and forgetting to do the cleanup (here, unlocking the lock), I want to use a scoped version of the lock. But having the scope optional forced me into using an allocation:\n ``` cpp\nvoid somethingProbablyUnsafe(ThreadingLock* lock)\n{\n  // unrelated code\n  // ...\n  \n\tstd::unique_ptr\u003cScopedLock\u003e scopedLock;\n\tif(lock)\n\t{\n\t\tscopedLock.reset(new ScopedLock(*lock));\n\t}\n\n\t// Complicated code with early outs.\n\t// ...\n}\n ```\nThis certainly solves the problem - the lock is still scoped and nobody needs to worry about having the lock unlocked. Way better than checking the lock variable at each return point. But it requires an allocation and no longer keeps the ScopedLock on the stack as it is intended to be, how awful! :(\n\nThe little template class in this repository solves this problem at the overhead of a single bool. Usage:\n ``` cpp\nvoid somethingProbablyUnsafe(ThreadingLock* lock)\n{\n  // unrelated code\n  // ...\n  \n\tOptionalScopedObject\u003cScopedLock\u003e scopedLock;\n\tif(lock)\n\t{\n\t\tscopedLock.construct(*lock);\n\t}\n\n\t// Complicated code with early outs.\n\t// ...\n}\n ```\n Scoped thread locks are of course only an example. The template can be used with any kind of scoped object that may or may not be required.\n \n*All this almost let forget you about the simple solution: Your scoped object should take a pointer and it should handle null.* (yeah, I forgot about that myself when I had this whole idea, thank you for pointing that out to me @ Christopher)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwumpf%2Foptionalscopedobject","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwumpf%2Foptionalscopedobject","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwumpf%2Foptionalscopedobject/lists"}