// Matrix Construct // // Copyright (C) Matrix Construct Developers, Authors & Contributors // Copyright (C) 2016-2019 Jason Volk // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice is present in all copies. The // full license for this software is available in the LICENSE file. #pragma once #define HAVE_IRCD_CTX_TRIT_H namespace ircd::ctx { struct trit; } namespace ircd { using ctx::trit; } /// Implementation of a tribool with custom semantics in a stackful coroutine /// environment. Tribools have three states: true, false, and unknown. Our goal /// here is to integrate this "unknown" property with the context-switching /// system. In a nutshell, when a `trit` in an unknown state is sampled, the /// context blocks until the `trit` leaves the unknown state. This action is /// based on the existing promise/future system and waiting for the known state /// can be thought of as a `future::get()`. The value of this endeavor /// though is greater than mere syntactic sugar for future. /// ``` /// if(trit == true) // context blocks here until the value is known /// ... // branch taken if value==true once known. /// /// ``` /// /// Overloaded logic operators make it possible to optimize /// conditional predicates by employing Kleene's strong logic of indeterminacy. /// This allows us to optimize these predicates for I/O rather than /// computation. In the example below, traditionally under boolean logic we /// evaluate trit[0] first, and if it's false, short-circuit evaluation elides /// observing trit[1]: /// ``` /// if(trit[0] && trit[1]) /// ... /// /// ``` /// Under the trilean logic in our system, we first test if trit[0] is known, /// because if it isn't, we can test if trit[1] is knowably false to conclude /// the predicate. The benefit is seen when these objects represent the result /// of latent asynchronous operations; head-of-line blocking is avoided in /// this case because any false value can abrogate any further blocking. /// struct ircd::ctx::trit { /// The boolean value state of true or false. This value is undefined when /// `unknown` is true bool value; /// Whether the boolean value is determinable/determined or not. We name /// this negatively such that any zero pre-initialization creates a known /// false value without requiring any code to be executed. bool unknown; trit(); }; inline ircd::ctx::trit::trit() :value{false} ,unknown{false} {}