0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-08 19:11:08 +01:00
construct/include/ircd/ctx/trit.h

73 lines
2.6 KiB
C++

// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2019 Jason Volk <jason@zemos.net>
//
// 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<bool>::get()`. The value of this endeavor
/// though is greater than mere syntactic sugar for future<bool>.
/// ```
/// 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}
{}