{"id":18736865,"url":"https://github.com/bitwizeshift/not_null","last_synced_at":"2025-04-12T19:32:04.241Z","repository":{"id":81485455,"uuid":"322150890","full_name":"bitwizeshift/not_null","owner":"bitwizeshift","description":"Non-nullable pointers with 0-overhead and no hidden runtime cost.","archived":false,"fork":false,"pushed_at":"2020-12-21T00:09:53.000Z","size":265,"stargazers_count":12,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-26T14:01:44.976Z","etag":null,"topics":["cpp","cpp11","cpp14","cpp17","modern-cpp","not-null","nullability"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bitwizeshift.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["bitwizeshift"],"custom":"https://www.buymeacoffee.com/dsq3XCcBE"}},"created_at":"2020-12-17T01:55:27.000Z","updated_at":"2025-02-06T14:42:25.000Z","dependencies_parsed_at":null,"dependency_job_id":"9ccbbcbd-ea70-4814-8821-c8fc5d74bb7f","html_url":"https://github.com/bitwizeshift/not_null","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwizeshift%2Fnot_null","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwizeshift%2Fnot_null/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwizeshift%2Fnot_null/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwizeshift%2Fnot_null/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bitwizeshift","download_url":"https://codeload.github.com/bitwizeshift/not_null/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248621215,"owners_count":21134777,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["cpp","cpp11","cpp14","cpp17","modern-cpp","not-null","nullability"],"created_at":"2024-11-07T15:22:48.714Z","updated_at":"2025-04-12T19:32:04.234Z","avatar_url":"https://github.com/bitwizeshift.png","language":"C++","readme":"# not_null\n\n[![Ubuntu Build Status](https://github.com/bitwizeshift/not_null/workflows/Ubuntu/badge.svg?branch=master)](https://github.com/bitwizeshift/not_null/actions?query=workflow%3AUbuntu)\n[![macOS Build Status](https://github.com/bitwizeshift/not_null/workflows/macOS/badge.svg?branch=master)](https://github.com/bitwizeshift/not_null/actions?query=workflow%3AmacOS)\n[![Windows Build Status](https://github.com/bitwizeshift/not_null/workflows/Windows/badge.svg?branch=master)](https://github.com/bitwizeshift/not_null/actions?query=workflow%3AWindows)\n[![Coverage Status](https://coveralls.io/repos/github/bitwizeshift/not_null/badge.svg?branch=master)](https://coveralls.io/github/bitwizeshift/not_null?branch=master)\n[![Github Issues](https://img.shields.io/github/issues/bitwizeshift/not_null.svg)](http://github.com/bitwizeshift/not_null/issues)\n\u003cbr\u003e\n[![Github Releases](https://img.shields.io/github/v/release/bitwizeshift/not_null.svg?include_prereleases)](https://github.com/bitwizeshift/not_null/releases)\n[![Bintray Releases](https://api.bintray.com/packages/bitwizeshift/public-conan/NotNull%3Anot_null/images/download.svg)](https://bintray.com/bitwizeshift/public-conan/NotNull%3Anot_null/_latestVersion)\n\u003cbr\u003e\n[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://godbolt.org/z/nPrnc7)\n\n**not_null** is a 0-overhead modern utility for ensuring non-nullability\nin a simple and coherent way.\n\nUnlike `gsl::not_null`, this type can work with move-only pointers like\n`std::unique_ptr`, and does not require runtime checks unless explicitly\nspecified.\n\n*Stop worrying about nulls, and use `not_null` today!*\n\n## Teaser\n\n```cpp\nauto register_widget(cpp::not_null\u003cstd::unique_ptr\u003cWidget\u003e\u003e p) -\u003e void\n{\n  legacy_service.adopt_widget(std::move(p).as_nullable());\n}\n\n...\n\n// use 'cpp::check_not_null' to check and validate that 'p' is not null\nregister_widget(cpp::check_not_null(std::move(p)));\n```\n\n\u003ckbd\u003e[Live Example](https://godbolt.org/z/nPrnc7)\u003c/kbd\u003e\n\n## Features\n\n* [x] Works with `unique_ptr`, and still allows nullability\n* [x] Zero-Overhead; `not_null` has no hidden additional runtime\n      or storage overhead.\n* [x] Written to be compatible with \u003ckbd\u003eC++11\u003c/kbd\u003e\n* [x] Single-header, **header-only** solution -- easily drops into any project\n* [x] No dependencies\n\n## Documentation\n\n* [Background](#background) \\\n  A background on the problem **not_null** solves\n* [Tutorial](doc/tutorial.md) \\\n  A quick pocket-guide to using **not_null**\n* [Installation](doc/installing.md) \\\n  For a quick guide on how to install/use this in other projects\n* [API Reference](https://bitwizeshift.github.io/not_null/api/latest/) \\\n  For doxygen-generated API information\n* [Attribution](doc/legal.md) \\\n  Information about how to attribute this project\n\n## Background\n\nWhen working in a codebase, it's often difficult to know when any given pointer\nmay legally contain a null pointer value. This requires the user to do one of\ntwo possible things:\n\n* Make an assumption that the pointer can never be `nullptr`, which risks the\n  posibility of a null-pointer dereference leading to undefined behavior, or\n* Always check for `nullptr` before using -- resulting in more complicated code\n  paths, more branches, and potential pessimizations\n\nThis is the driving force behind a `not_null` utility. The Guidelines Support\nLibrary offers `gsl::not_null` to attempt to satisfy this, though this has\ntwo notable limitations:\n\n* Construction and assignment of `not_null` is implicit, and requires runtime\n  checks unconditionally (which may result in a contract violation); for example:\n  ```cpp\n  // Performs check that the pointer is not null, when the expression can never\n  // take on the form of a non-null pointer\n  gsl::not_null\u003cint*\u003e p = new int{42};\n  ```\n\n* it does not work with move-only pointer types like `unique_ptr`, for example:\n  ```cpp\n  gsl::not_null\u003cstd::unique_ptr\u003cint\u003e\u003e p = std::make_unique\u003cint\u003e(42);\n  // This errors due to 'p' not being movable!\n  gsl::not_null\u003cstd::unique_ptr\u003cint\u003e\u003e q = std::move(p);\n  ```\n\nThis is where this library comes in.\n\nRather than allow implicit construction and assignment from the underlying\npointer, this library takes the hard stance of **correct on construction**,\nwhich uses factory functions to produce the `not_null` objects. Two factories\nare presented:\n\n* `check_not_null`, which checks a pointer for nullability before raising a\n  contract violation, which by default is thrown as an exception, or\n* `assume_not_null`, which does no checking to produce the `not_null` and has\n  zero overhead, which is to be used for known non-null values\n\nWith these, consumers are _required_ to consent to a check, or explicitly\nstate that their pointers are non-null, to reduce errors. This leaves any\nremaining uses of `not_null` as nothing more than a 0-overhead wrapper; making\nany runtime checks a manully consented operation. For example:\n\n```cpp\n// No check performed, since the expression can never be null!\ncpp::not_null\u003cint*\u003e p = cpp::assume_not_null(new int{42});\n\n// Get pointer from API that we *expect* to be null, but cannot guarantee\nauto q = cpp::check_not_null(get_pointer());\n```\n\nAdditionally, `not_null` allows for move-constructors and move-assignment, since\nreusing an object after a move is generally a logic-error, and there are many\npieces of tooling that will check for such a case. This allows better interop\nwith types like `unique_ptr`, and also allows for this `not_null` to communicate\nwith more legacy APIs by propagating such pointers out efficiently:\n\n```cpp\n// Should never be null, but not yet refactored to be 'not_null'\nauto old_api(std::unique_ptr\u003cWidget\u003e p) -\u003e void;\n\nauto new_api(cpp::not_null\u003cstd::unique_ptr\u003cWidget\u003e\u003e p) -\u003e void\n{\n  // Extract the move-only unique_ptr, and push along to 'old_api'\n  old_api(std::move(p).as_nullable());\n}\n```\n\n## Optional Features\n\nThe defaults for this library should satisfy most consumers needs; however\n**not_null** supports two optional features that may be controlled\nthrough preprocessor symbols:\n\n1. Using a custom namespace, and\n2. Disabling all exceptions\n\n### Using a Custom Namespace\n\nThe `namespace` that `not_null` is defined in is configurable. By default,\nit is defined in `namespace cpp`; however this can be toggled by defining\nthe preprocessor token `NOT_NULL_NAMESPACE` to be the name of the desired\nnamespace.\n\nThis could be done either through a `#define` preprocessor directive prior to\ninclusion:\n\n```cpp\n#define NOT_NULL_NAMESPACE example\n#include \u003cnot_null.hpp\u003e\n\nauto test(example::not_null\u003cint*\u003e p) -\u003e void;\n```\n\n\u003ckbd\u003e[Try Online](https://godbolt.org/z/1nd8Wj)\u003c/kbd\u003e\n\nOr it could also be defined using a compiler flag with `-D` or `/D`, such\nas:\n\n`g++ -std=c++11 -DNOT_NULL_NAMESPACE=example test.cpp`\n\n```cpp\n#include \u003cnot_null.hpp\u003e\n\nauto test(example::not_null\u003cint*\u003e p) -\u003e void;\n```\n\n\u003ckbd\u003e[Try Online](https://godbolt.org/z/x6rjej)\u003c/kbd\u003e\n\n### Disabling Exceptions\n\nBy default, `not_null` will throw a `cpp::not_null_contract_violation` when\nthe contract has been violated (during factory construction).\n\nHowever, it is realized that not all developers appreciate or use exceptions,\nand that environments that disable exception handling specifically may\nerror due to the existence of a `throw` expression. To account for this\npossibility, exceptions may be disabled through the introduction of a simple\nmacro preprocessor symbol: `NOT_NULL_DISABLE_EXCEPTIONS`.\n\nIn doing so, contract-violations will now behave differently:\n\n* Contract violations will call `std::abort`, causing immediate termination\n  (and often, core-dumps for diagnostic purposes)\n* Contract violations will print directly to `stderr` to allow context for the\n  termination\n* Since exceptions are disabled, there is no way to perform a proper stack\n  unwinding -- so destructors will _not be run_. There is simply no way to\n  allow for proper RAII cleanup without exceptions in this case.\n\n\u003ckbd\u003e[Try Online](https://godbolt.org/z/5na3KW)\u003c/kbd\u003e\n\n\n## Compiler Compatibility\n\n**not_null** is compatible with any compiler capable of compiling valid\n\u003ckbd\u003eC++11\u003c/kbd\u003e. Specifically, this has been tested and is known to work\nwith:\n\n* GCC 5, 6, 7, 8, 9, 10\n* Clang 3.5, 3.6, 3.7, 3.8, 3.9, 4, 5, 6, 7, 8, 9, 10, 11\n* Apple Clang (Xcode) 10.3, 11.2, 11.3, 12.3\n* Visual Studio 2015, 2017, 2019\n\nLatest patch level releases are assumed in the versions listed above.\n\n## License\n\n\u003cimg align=\"right\" src=\"http://opensource.org/trademarks/opensource/OSI-Approved-License-100x137.png\"\u003e\n\n**not_null** is licensed under the\n[MIT License](http://opensource.org/licenses/MIT):\n\n\u003e Copyright \u0026copy; 2019 Matthew Rodusek\n\u003e\n\u003e Permission is hereby granted, free of charge, to any person obtaining a copy\n\u003e of this software and associated documentation files (the \"Software\"), to deal\n\u003e in the Software without restriction, including without limitation the rights\n\u003e to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\u003e copies of the Software, and to permit persons to whom the Software is\n\u003e furnished to do so, subject to the following conditions:\n\u003e\n\u003e The above copyright notice and this permission notice shall be included in all\n\u003e copies or substantial portions of the Software.\n\u003e\n\u003e THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\u003e IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\u003e FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\u003e AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\u003e LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\u003e OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n\u003e SOFTWARE.\n\n## References\n\n* [`alloy::core::not_null`](https://github.com/bitwizeshift/Alloy/blob/78abb03feff35ead86888f445d48acbe72ada8c5/lib/alloy-core/include/alloy/core/utilities/not_null.hpp):\n  the original implementation that this utility is based on.\n* [`gsl::not_null`](https://raw.githubusercontent.com/microsoft/GSL/master/include/gsl/pointers):\n  a competing implementation offered as part of the core-guidelines support\n  library\n* [`doxygen::oxygen::nn`](https://raw.githubusercontent.com/dropbox/nn/master/nn.hpp):\n  an alternative to nullability offered by Dropbox (archived)\n","funding_links":["https://github.com/sponsors/bitwizeshift","https://www.buymeacoffee.com/dsq3XCcBE"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitwizeshift%2Fnot_null","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbitwizeshift%2Fnot_null","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitwizeshift%2Fnot_null/lists"}