Library of Assembled Shared Sources
no_none.h
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2025 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43#pragma once
44
45#include "../config/config.h"
46
47namespace lass::python
48{
49
50/** Wrapper to prevent `None` values being passed to and from Python.
51 *
52 * Use this class to wrap a value of type `T` that could be `None` in Python (for example,
53 * a pointer type), but you want to ensure that the value is always valid and not `None`.
54 *
55 * ```
56 * using ShaderPtr = std::shared_ptr<Shader>;
57 * NoNone<ShaderPtr> subtract(const NoNone<ShaderPtr>& a, const NoNone<ShaderPtr>& b)
58 * {
59 * return ShaderPtr(new SubtractShaders(a, b));
60 * }
61 * PY_MODULE_FUNCTION_DOC(shader_graph, subtract, "Subtract two shaders")
62 * ```
63 *
64 * Works in both directions: from and to Python. In case a `None` value is passed or
65 * returned, it will raise a Python `TypeError` instead.
66 *
67 * @note This class does **ONLY** prevents `None` values from crossing the Python/C++
68 * boundary. It does **NOT** provide any other runtime or compile-time checks. You can
69 * happily put a `nullptr` in a `NoNone<T>` as long as you don't pass it to Python.
70 *
71 * Built-in support for NoNone is provided for raw pointers `T*`, util::SharedPtr<T>,
72 * and `std::shared_ptr<T>`. To support your own types, you must specialize PyExportTraits:
73 * see PyExportTraitsNoNone for more information.
74 *
75 * @ingroup Python
76 * @sa PyExportTraitsNoNone
77 * @sa PyExportTraits<NoNone<T*>>
78 * @sa PyExportTraits<NoNone<util::SharedPtr<T,S,C>>>
79 * @sa PyExportTraits<NoNone<std::shared_ptr<T>>>
80 * @sa MaybeNone
81 */
82template <typename T>
83class NoNone
84{
85public:
86 NoNone(const T& x = T()): value_(x) {}
87
88 T& reference() { return value_; } ///< Return reference to wrapped value
89 const T& reference() const { return value_; } ///< Return reference to wrapped value
90
91 operator T&() { return value_; }
92 operator const T&() const { return value_; }
93 auto operator->() const { return value_.operator->(); }
94 auto operator->() { return value_.operator->(); }
95 auto& operator*() const { return value_.operator*(); }
96 auto& operator*() { return value_.operator*(); }
97
98 bool operator!() const { return !value_; }
99 explicit operator bool() const { return static_cast<bool>(value_); }
100
101#if __cpp_impl_three_way_comparison
102 auto operator<=>(const NoNone& other) const = default;
103#endif
104
105private:
106 T value_;
107};
108
109#if !__cpp_impl_three_way_comparison
110
111template <typename T> bool operator==(const NoNone<T>& a, const NoNone<T>& b) { return a.reference() == b.reference(); }
112template <typename T> bool operator!=(const NoNone<T>& a, const NoNone<T>& b) { return a.reference() != b.reference(); }
113template <typename T> bool operator<(const NoNone<T>& a, const NoNone<T>& b) { return a.reference() < b.reference(); }
114template <typename T> bool operator>(const NoNone<T>& a, const NoNone<T>& b) { return a.reference() > b.reference(); }
115template <typename T> bool operator<=(const NoNone<T>& a, const NoNone<T>& b) { return a.reference() <= b.reference(); }
116template <typename T> bool operator>=(const NoNone<T>& a, const NoNone<T>& b) { return a.reference() >= b.reference(); }
117template <typename T> bool operator==(const NoNone<T>& a, std::nullptr_t b) { return a.reference() == b; }
118template <typename T> bool operator!=(const NoNone<T>& a, std::nullptr_t b) { return a.reference() != b; }
119template <typename T> bool operator==(std::nullptr_t a, const NoNone<T>& b) { return a == b.reference(); }
120template <typename T> bool operator!=(std::nullptr_t a, const NoNone<T>& b) { return a != b.reference(); }
121
122#endif
123
124}
Wrapper to prevent None values being passed to and from Python.
Definition no_none.h:84
T & reference()
Return reference to wrapped value.
Definition no_none.h:88
const T & reference() const
Return reference to wrapped value.
Definition no_none.h:89
Comprehensive C++ to Python binding library.