/////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2015 Microsoft Corporation. All rights reserved. // // This code is licensed under the MIT License (MIT). // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /////////////////////////////////////////////////////////////////////////////// #ifndef GSL_TRANSITION_H #define GSL_TRANSITION_H #include // for Ensures, Expects #include // for gsl::not_null #if defined(_MSC_VER) && _MSC_VER < 1910 #pragma push_macro("constexpr") #define constexpr /*constexpr*/ #endif // defined(_MSC_VER) && _MSC_VER < 1910 namespace gsl_helpers { // // sloppy_not_null // // Restricts a pointer or smart pointer to only hold non-null values, // // - provides a sloppy (i.e. no explicit contructor from T) wrapper of gsl::not_null // - is temporary, only to be used to incrementally transition of code // using older version of gsl::not_null to the new one that made the constructor explicit // // To make the transition: // // - replace all occurences of gsl::not_null in your code by sloppy_not_null // variant: rename gsl::not_null by NotNull by including the following in your code, // foe example, in a common include file: // // template // using NotNull = gsl::not_null; // // compile using old version of GSL // change GSL version and replace gsl::not_null by gsl_helpers::sloppy_not_null // in the added code lines above // // - compile - compilation should be successful // - replace some sloppy_not_nulls by gsl::not_null, fix compilation erros, // redesign as needed, compile and test // - repeat until no sloppy_not_nulls remain // template class sloppy_not_null: public gsl::not_null { public: template ::value>> constexpr sloppy_not_null(U&& u) : gsl::not_null(std::forward(u)) {} template ::value>> constexpr sloppy_not_null(T u) : gsl::not_null(u) {} template ::value>> constexpr sloppy_not_null(const gsl::not_null& other) : gsl::not_null(other) {} sloppy_not_null(sloppy_not_null&& other) = default; sloppy_not_null(const sloppy_not_null& other) = default; sloppy_not_null& operator=(const sloppy_not_null& other) = default; sloppy_not_null& operator=(const gsl::not_null& other) { gsl::not_null::operator=(other); return *this; } // prevents compilation when someone attempts to assign a null pointer constant sloppy_not_null(std::nullptr_t) = delete; sloppy_not_null& operator=(std::nullptr_t) = delete; // unwanted operators...pointers only point to single objects! sloppy_not_null& operator++() = delete; sloppy_not_null& operator--() = delete; sloppy_not_null operator++(int) = delete; sloppy_not_null operator--(int) = delete; sloppy_not_null& operator+=(std::ptrdiff_t) = delete; sloppy_not_null& operator-=(std::ptrdiff_t) = delete; void operator[](std::ptrdiff_t) const = delete; }; // more unwanted operators template std::ptrdiff_t operator-(const sloppy_not_null&, const sloppy_not_null&) = delete; template sloppy_not_null operator-(const sloppy_not_null&, std::ptrdiff_t) = delete; template sloppy_not_null operator+(const sloppy_not_null&, std::ptrdiff_t) = delete; template sloppy_not_null operator+(std::ptrdiff_t, const sloppy_not_null&) = delete; } // namespace gsl namespace std { template struct hash> { std::size_t operator()(const gsl_helpers::sloppy_not_null& value) const { return hash{}(value); } }; } // namespace std #if defined(_MSC_VER) && _MSC_VER < 1910 #undef constexpr #pragma pop_macro("constexpr") #endif // defined(_MSC_VER) && _MSC_VER < 1910 #endif // GSL_TRANSITION_H