mirror of
https://github.com/matrix-construct/construct
synced 2024-11-18 07:50:57 +01:00
74 lines
2.6 KiB
C
74 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}
|
||
|
{}
|