Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- This module is based on code in the std.typecons module in the standard library of the D programming language. The authors of std.typecons deserve credit and thanks, and are listed at the top of the source code for the module, which is available here:
- https://github.com/D-Programming-Language/phobos/blob/master/std/typecons.d
- Copyright (c) 2013, w0rp <moebiuspersona@gmail.com>
- All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- 1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- module option;
- import std.exception;
- import std.typecons;
- import std.stdio;
- struct Option(T) if(is(T == class)) {
- private T _value;
- this(T value) {
- _value = value;
- }
- this(Nullable!T value) {
- if (!value.isNull)
- {
- _value = value;
- }
- }
- @property @safe const pure nothrow
- bool isNull() {
- return _value is null;
- }
- @safe pure nothrow
- void opAssign(T value) {
- _value = value;
- }
- @safe pure
- void opAssign(Nullable!T value) {
- if (!value.isNull)
- {
- _value = value;
- }
- }
- @safe pure nothrow nullify() {
- _value = null;
- }
- @property @safe pure nothrow inout(T) get() inout {
- enum message = "Called `get' on null Option!" ~ T.stringof ~ ".";
- assert(_value !is null, message);
- return _value;
- }
- alias get this;
- }
- struct Option(T) if(!is(T == class)) {
- private T _value;
- private bool _isNull = true;
- this(T value) {
- _value = value;
- _isNull = false;
- }
- // The defaults work here.
- this(typeof(null) value) {}
- this(Nullable!T value) {
- if (!value.isNull) {
- _value = value;
- _isNull = false;
- }
- }
- @property @safe const pure nothrow
- bool isNull() {
- return _isNull;
- }
- @safe pure nothrow
- void opAssign(T value) {
- _value = value;
- _isNull = false;
- }
- @safe pure nothrow
- void opAssign(typeof(null) value) {
- nullify();
- }
- @safe pure
- void opAssign(Nullable!T value) {
- if (!value.isNull) {
- _value = value;
- _isNull = false;
- }
- }
- @safe pure nothrow nullify() {
- _value = T.init;
- _isNull = true;
- }
- @property @safe pure nothrow
- inout(T) get() inout {
- enum message = "Called `get' on null Option!" ~ T.stringof ~ ".";
- assert(!_isNull, message);
- return _value;
- }
- alias get this;
- }
- // Test that Option works for classes.
- unittest {
- class MyClass { }
- Option!MyClass test = null;
- assert(test.isNull);
- assertThrown!Throwable(test.get);
- }
- unittest {
- class MyClass { }
- Option!MyClass test = new MyClass();
- test = null;
- assert(test.isNull);
- assertThrown!Throwable(test.get);
- }
- unittest {
- class MyClass { }
- Option!MyClass test = new MyClass();
- assert(!test.isNull);
- assertNotThrown!Throwable(test.get);
- }
- unittest {
- class MyClass { }
- Option!MyClass test;
- test = new MyClass();
- assert(!test.isNull);
- assertNotThrown!Throwable(test.get);
- }
- // Test that option works for primitives.
- unittest {
- Option!int test;
- assert(test.isNull);
- assertThrown!Throwable(test.get);
- }
- unittest {
- Option!int test = 3;
- test.nullify();
- assert(test.isNull);
- assertThrown!Throwable(test.get);
- }
- unittest {
- Option!int test = 4;
- assert(!test.isNull);
- assertNotThrown!Throwable(test.get);
- }
- unittest {
- Option!int test;
- test = 4;
- assert(!test.isNull);
- assertNotThrown!Throwable(test.get);
- }
- // Test the hook for assigning null to primitives.
- unittest {
- Option!int test = null;
- }
- unittest {
- Option!int test;
- test = null;
- }
- // Test that option supports Nullable for classes.
- unittest {
- class MyClass { }
- Nullable!MyClass nullableInstance;
- Option!MyClass optInstance = nullableInstance;
- assert(optInstance.isNull);
- assertThrown!Throwable(optInstance.get);
- }
- unittest {
- class MyClass { }
- MyClass instance = new MyClass();
- Nullable!MyClass nullableInstance = instance;
- Option!MyClass optInstance = nullableInstance;
- assert(!optInstance.isNull);
- assertNotThrown!Throwable(optInstance.get);
- assert(optInstance == instance);
- }
- // Test that option supports Nullable for primitives.
- unittest {
- Nullable!int nullableInt;
- Option!int optInt = nullableInt;
- assert(optInt.isNull);
- assertThrown!Throwable(optInt.get);
- }
- unittest {
- Nullable!int nullableInt = 3;
- Option!int optInt = nullableInt;
- assert(!optInt.isNull);
- assertNotThrown!Throwable(optInt.get);
- assert(optInt == 3);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement