diff --git a/README.md b/README.md index 8a031be..7fb41ff 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # go-stackage -[![Go Report Card](https://goreportcard.com/badge/github.com/JesseCoretta/go-stackage)](https://goreportcard.com/report/github.com/JesseCoretta/go-stackage) [![Go Reference](https://pkg.go.dev/badge/github.com/JesseCoretta/go-stackage.svg)](https://pkg.go.dev/github.com/JesseCoretta/go-stackage) [![CodeQL](https://github.com/JesseCoretta/go-stackage/workflows/CodeQL/badge.svg)](https://github.com/JesseCoretta/go-stackage/actions/workflows/github-code-scanning/codeql) [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](https://github.com/JesseCoretta/go-stackage/blob/main/LICENSE) [![codecov](https://codecov.io/gh/JesseCoretta/go-stackage/graph/badge.svg?token=RLW4DHLKQP)](https://codecov.io/gh/JesseCoretta/go-stackage) [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/JesseCoretta/go-stackage/issues) [![Experimental](https://img.shields.io/badge/experimental-blue?logoColor=blue&label=%F0%9F%A7%AA%20%F0%9F%94%AC&labelColor=blue&color=gray)](https://github.com/JesseCoretta/JesseCoretta/blob/main/EXPERIMENTAL.md) [![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/jessecoretta/go-stackage/go.yml?event=push)](https://github.com/JesseCoretta/go-stackage/actions/workflows/go.yml) [![Author](https://img.shields.io/badge/author-Jesse_Coretta-darkred?label=%F0%9F%94%BA&labelColor=indigo&color=maroon)](mailto:jesse.coretta@icloud.com) [![GitHub release (with filter)](https://img.shields.io/github/v/release/JesseCoretta/go-stackage)](https://github.com/JesseCoretta/go-stackage/releases) [![Help Animals](https://img.shields.io/badge/help_animals-gray?label=%F0%9F%90%BE%20%F0%9F%98%BC%20%F0%9F%90%B6&labelColor=yellow)](https://github.com/JesseCoretta/JesseCoretta/blob/main/DONATIONS.md) +[![Go Report Card](https://goreportcard.com/badge/github.com/JesseCoretta/go-stackage)](https://goreportcard.com/report/github.com/JesseCoretta/go-stackage) [![Go Reference](https://pkg.go.dev/badge/github.com/JesseCoretta/go-stackage.svg)](https://pkg.go.dev/github.com/JesseCoretta/go-stackage) [![CodeQL](https://github.com/JesseCoretta/go-stackage/workflows/CodeQL/badge.svg)](https://github.com/JesseCoretta/go-stackage/actions/workflows/github-code-scanning/codeql) [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](https://github.com/JesseCoretta/go-stackage/blob/main/LICENSE) [![codecov](https://codecov.io/gh/JesseCoretta/go-stackage/graph/badge.svg?token=RLW4DHLKQP)](https://codecov.io/gh/JesseCoretta/go-stackage) [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/JesseCoretta/go-stackage/issues) [![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/jessecoretta/go-stackage/go.yml?event=push)](https://github.com/JesseCoretta/go-stackage/actions/workflows/go.yml) [![Author](https://img.shields.io/badge/author-Jesse_Coretta-darkred?label=%F0%9F%94%BA&labelColor=indigo&color=maroon)](mailto:jesse.coretta@icloud.com) [![GitHub release (with filter)](https://img.shields.io/github/v/release/JesseCoretta/go-stackage)](https://github.com/JesseCoretta/go-stackage/releases) [![Help Animals](https://img.shields.io/badge/help_animals-gray?label=%F0%9F%90%BE%20%F0%9F%98%BC%20%F0%9F%90%B6&labelColor=yellow)](https://github.com/JesseCoretta/JesseCoretta/blob/main/DONATIONS.md) ![stacks03](https://github.com/JesseCoretta/go-stackage/assets/74126726/ec6429ac-d698-413b-8c1c-0ac8dc1e301c) @@ -17,7 +17,7 @@ The main goal of this package is provide an extremely reliable and accommodating - Stack instances are either LIFO (stack based, default) or FIFO (queue based) - FIFO is First-In/First-Out (like a line at your favorite deli: first come, first serve) - LIFO is Last-In/First-Out (like those plate-stacking apparatuses found in restaurant kitchens, in which the first plate inserted shall be the last plate removed) - - Flexible Stack configuration controls, allowing custom stringer presentation, push controls and validity-checking policies to be imposed + - Flexible Stack configuration controls, allowing custom stringer presentation, sorting closures, push controls and validity-checking policies to be imposed - Recursive design - Stacks can reside in Stacks. Conditions can reside in Stacks. Conditions can contain other Stacks. Whatever! - Eligible values are easily navigated using the Stack.Traverse method using an ordered sequence of indices, or slice index numbers - Conversely, recursion capabilities can also be easily disabled per instance! @@ -36,7 +36,7 @@ The main goal of this package is provide an extremely reliable and accommodating ## Status -Although fairly well-tested, this package is in its early stages and is undergoing active development. It should only be used in production environments while under heavy scrutiny and with great care. +This package is no longer considered experimental, as it is currently in use in the wild with impressive results. ## License @@ -75,6 +75,14 @@ func (r MyStack) String() string { // return the result from a "TYPE CAST -> EXEC" call return stackage.Stack(r).String() } + +// For added convenience, adopters can write their own private "cast" +// method for quick transformation back to the derived Stack type. +// This allows easy access to base methods which the adopter has not +// explicitly wrapped. +func (r MyStack) cast() stackage.Stack { + return stackage.Stack(r) +} ``` The procedure would be identical for a Condition alias -- just change the name and the derived stackage type from the first example line and modify as desired. diff --git a/cfg.go b/cfg.go index caf5eaa..9f70dff 100644 --- a/cfg.go +++ b/cfg.go @@ -28,32 +28,34 @@ type nodeConfig struct { err error // error pertaining to the outer type state (Condition/Stack) aux Auxiliary // auxiliary admin-related object storage, user managed - typ stackType // stacks only: defines the typ/kind of stack - sym string // stacks only: user-controlled symbol char(s) - ljc string // [list] stacks only: joining delim - mtx *sync.Mutex // stacks only: optional locking system - ldr *time.Time // for lock duration; ephemeral, nil if not locked / no locking capabilities - ord bool // true = FIFO, false = LIFO (default); applies to stacks only + lss func(int, int) bool // stacks only: for sort.Interface qualification + typ stackType // stacks only: defines the typ/kind of stack + sym string // stacks only: user-controlled symbol char(s) + ljc string // [list] stacks only: joining delim + mtx *sync.Mutex // stacks only: optional locking system + ldr *time.Time // for lock duration; ephemeral, nil if not locked / no locking capabilities + ord bool // true = FIFO, false = LIFO (default); applies to stacks only } /* Auxiliary is a map[string]any type alias extended by this package. It -can be created within any Stack instance when [re]initialized using -the SetAuxiliary method extended through instances of the Stack type, -and can be accessed using the Auxiliary() method in similar fashion. +can be created within any [Stack] instance when [re]initialized using +the [Stack.SetAuxiliary] method extended through instances of the [Stack] +type, and can be accessed using the [Stack.Auxiliary] method in similar +fashion. -The Auxiliary type extends four (4) methods: Get, Set, Len and Unset. -These are purely for convenience. Given that instances of this type -can easily be cast to standard map[string]any by the user, the use of -these methods is entirely optional. +The [Auxiliary] type extends four (4) methods: [Auxiliary.Get], [Auxiliary.Set], +[Auxiliary.Len] and [Auxiliary.Unset]. These are purely for convenience. Given +that instances of this type can easily be cast to standard map[string]any by the +user, the use of these methods is entirely optional. -The Auxiliary map instance is available to be leveraged in virtually +The [Auxiliary] map instance is available to be leveraged in virtually any way deemed appropriate by the user. Its primary purpose is for storage of any instance(s) pertaining to the *administration of the stack*, as opposed to the storage of content normally submitted *into* -said stack. +said [Stack]. -Examples of suitable instance types for storage within the Auxiliary +Examples of suitable instance types for storage within the [Auxiliary] map include, but are certainly not limited to: - HTTP server listener / mux @@ -66,7 +68,7 @@ map include, but are certainly not limited to: - text/template instances - channels -Which instances are considered suitable for storage within Auxiliary map +Which instances are considered suitable for storage within [Auxiliary] map instances is entirely up to the user. This package shall not impose ANY controls or restrictions regarding the content within this instances of this type, nor its behavior. @@ -100,7 +102,7 @@ func (r Auxiliary) Get(key string) (value any, ok bool) { /* Set associates key with value, and assigns to receiver instance. See -also the Unset method. +also the [Auxiliary.Unset] method. If the receiver is not initialized, a new allocation is made. */ @@ -113,7 +115,7 @@ func (r Auxiliary) Set(key string, value any) Auxiliary { /* Unset removes the key/value pair, identified by key, from the receiver -instance, if found. See also the Set method. +instance, if found. See also the [Auxiliary.Set] method. This method internally calls the following builtin: diff --git a/cond.go b/cond.go index 8af914f..01f5ce5 100644 --- a/cond.go +++ b/cond.go @@ -20,7 +20,7 @@ string construct against which the expression value (ex) is to be evaluated in some manner. The disposition of the evaluation is expressed through one (1) of -several ComparisonOperator (op) instances made available through +several [ComparisonOperator] (op) instances made available through this package: - Eq, or "equal to" (=) @@ -36,17 +36,17 @@ defined Operator interface. By default, permitted expression (ex) values must honor these guidelines: - Must be a non-zero string, OR ... - - Must be a valid instance of Stack (or an *alias* of Stack that is convertible back to the Stack type), OR ... - - Must be a valid instance of any type that exports a stringer method (String()) intended to produce the Condition's final expression string representation + - Must be a valid instance of [Stack] (or an *alias* of [Stack] that is convertible back to the [Stack] type), OR ... + - Must be a valid instance of any type that exports a stringer method (String()) intended to produce the [Condition] instances final expression string representation -However when a PushPolicy function or method is added to an instance of this type, +However when a [PushPolicy] function or method is added to an instance of this type, greater control is afforded to the user in terms of what values will be accepted, as well as the quality or state of such values. -Instances of this type -- similar to Stack instances -- MUST be initialized before use. -Initialization can occur as a result of executing the Cond package-level function, or -using the Init method extended through instances of this type. Initialization state may -be checked using the IsInit method. +Instances of this type -- similar to [Stack] instances -- MUST be initialized before use. +Initialization can occur as a result of executing the [Cond] package-level function, or +using the [Condition.Init] method extended through instances of this type. Initialization +state may be checked using the [Condition.IsInit] method. */ type Condition struct { *condition @@ -99,7 +99,7 @@ SetAuxiliary assigns aux, as initialized and optionally populated as needed by the user, to the receiver instance. The aux input value may be nil. -If no variadic input is provided, the default Auxiliary allocation +If no variadic input is provided, the default [Auxiliary] allocation shall occur. Note that this method shall obliterate any instance that may already @@ -131,7 +131,7 @@ func (r *condition) setAuxiliary(aux ...Auxiliary) { } /* -Auxiliary returns the instance of Auxiliary from within the receiver. +Auxiliary returns the instance of [Auxiliary] from within the receiver. */ func (r Condition) Auxiliary() (aux Auxiliary) { if r.IsInit() { @@ -141,7 +141,7 @@ func (r Condition) Auxiliary() (aux Auxiliary) { } /* -auxiliary is a private method called by Condition.Auxiliary. +auxiliary is a private method called by [Condition.Auxiliary]. */ func (r condition) auxiliary() (aux Auxiliary) { aux = r.cfg.aux @@ -172,8 +172,8 @@ func (r *condition) setKeyword(kw any) { } /* -SetOperator sets the receiver's comparison operator using the -specified Operator-qualifying input argument (op). +SetOperator sets the receiver's [ComparisonOperator] using the +specified [Operator]-qualifying input argument (op). */ func (r Condition) SetOperator(op Operator) Condition { if r.IsInit() { @@ -190,7 +190,8 @@ func (r *condition) setOperator(op Operator) { /* SetExpression sets the receiver's expression value(s) using the -specified ex input argument. +specified ex input argument. See also the [Condition.Expression] +method. */ func (r Condition) SetExpression(ex any) Condition { if r.IsInit() { @@ -206,12 +207,12 @@ func (r *condition) setExpression(ex any) { } /* -SetLogLevel enables the specified LogLevel instance(s), thereby +SetLogLevel enables the specified [LogLevel] instance(s), thereby instructing the logging subsystem to accept events for submission and transcription to the underlying logger. Users may also sum the desired bit values manually, and cast the -product as a LogLevel. For example, if STATE (4), DEBUG (8) and +product as a [LogLevel]. For example, if STATE (4), DEBUG (8) and TRACE (32) logging were desired, entering LogLevel(44) would be the same as specifying LogLevel3, LogLevel4 and LogLevel6 in variadic fashion. @@ -229,7 +230,7 @@ func (r *condition) setLogLevel(l ...any) { /* LogLevels returns the string representation of a comma-delimited list -of all active LogLevel values within the receiver. +of all active [LogLevel] values within the receiver. */ func (r Condition) LogLevels() (l string) { if r.IsInit() { @@ -243,7 +244,7 @@ func (r condition) logLevels() (l string) { } /* -UnsetLogLevel disables the specified LogLevel instance(s), thereby +UnsetLogLevel disables the specified [LogLevel] instance(s), thereby instructing the logging subsystem to discard events submitted for transcription to the underlying logger. */ @@ -275,11 +276,11 @@ The following types/values are permitted: - int: 0 will turn logging off - int: 1 will set basic STDOUT logging - int: 2 will set basic STDERR logging - - *log.Logger: user-defined *log.Logger instance will be set; it should not be nil + - *[log.Logger]: user-defined *[log.Logger] instance will be set; it should not be nil Case is not significant in the string matching process. -Logging may also be set globally using the SetDefaultLogger +Logging may also be set globally using the [SetDefaultLogger] package level function. Similar semantics apply. */ func (r Condition) SetLogger(logger any) Condition { @@ -401,9 +402,9 @@ func (r condition) getCat() string { } /* -SetCategory assigns the provided string to the receiver internal category value. -This allows for a means of identifying a particular kind of Condition in the midst -of many. +SetCategory assigns the provided string to the receiver internal category +value. This allows for a means of identifying a particular kind of [Condition] +in the midst of many. */ func (r Condition) SetCategory(cat string) Condition { if r.IsInit() { @@ -424,8 +425,8 @@ func (r Condition) Category() (cat string) { } /* -Cond returns an instance of Condition bearing the provided component values. -This is intended to be used in situations where a Condition instance can be +Cond returns an instance of [Condition] bearing the provided component values. +This is intended to be used in situations where a [Condition] instance can be created in one shot. */ func Cond(kw any, op Operator, ex any) (c Condition) { @@ -444,8 +445,8 @@ the receiver instance shall be totally annihilated. This method is niladic and fluent in nature. No input is required, and the only element returned is the receiver itself. -This method may be useful in situations where a Condition will be assembled in a -"piecemeal" fashion (i.e.: incrementally), or if a Condition instance is slated to +This method may be useful in situations where a [Condition] will be assembled in a +"piecemeal" fashion (i.e.: incrementally), or if a [Condition] instance is slated to be repurposed for use elsewhere (possibly in a repetative manner). */ func (r *Condition) Init() Condition { @@ -455,7 +456,7 @@ func (r *Condition) Init() Condition { /* SetID assigns the provided string value (or lack thereof) to the receiver. -This is optional, and is usually only needed in complex Condition structures +This is optional, and is usually only needed in complex [Condition] structures in which "labeling" certain components may be advantageous. It has no effect on an evaluation, nor should a name ever cause a validity check to fail. @@ -480,15 +481,15 @@ Len returns a "perceived" abstract length relating to the content (or lack thereof) assigned to the receiver instance: - An uninitialized or zero instance returns zero (0) - - An initialized instance with no Expression assigned (nil) returns zero (0) - - A Stack or Stack type alias assigned as the Expression shall impose its own stack length as the return value (even if zero (0)) + - An initialized instance with no [Condition.Expression] assigned (nil) returns zero (0) + - A [Stack] or [Stack] type alias assigned as the [Condition.Expression] shall impose its own length as the return value (even if zero (0)) -All other type instances assigned as an Expression shall result in a +All other type instances assigned as an [Condition.Expression] shall result in a return of one (1); this includes slice types, maps, arrays and any other type that supports multiple values. -This capability was added to this type to mirror that of the Stack type in -order to allow additional functionality to be added to the Interface interface. +This capability was added to this type to mirror that of the [Stack] type in +order to allow additional functionality to be added to the [Interface] interface. */ func (r Condition) Len() int { if !r.IsInit() { @@ -511,7 +512,7 @@ Addr returns the string representation of the pointer address for the receiver. This may be useful for logging or debugging operations. -Note: this method calls fmt.Sprintf. +Note: this method calls [fmt.Sprintf]. */ func (r Condition) Addr() (addr string) { if r.IsInit() { @@ -536,7 +537,7 @@ func (r Condition) ID() (id string) { /* IsInit will verify that the internal pointer instance of the receiver has been properly initialized. This method executes a preemptive execution of -the IsZero method. +the [Condition.IsZero] method. */ func (r Condition) IsInit() (is bool) { if !r.IsZero() { @@ -567,8 +568,8 @@ with the state of the receiver. Non-serious (interim) errors such as denied pushes, capacity violations, etc., are not shown by this method. -If a ValidityPolicy was set within the receiver, it shall be executed here. -If no ValidityPolicy was specified, only elements pertaining to basic viability +If a [ValidityPolicy] was set within the receiver, it shall be executed here. +If no [ValidityPolicy] was specified, only elements pertaining to basic viability are checked. */ func (r Condition) Valid() (err error) { @@ -611,12 +612,12 @@ func (r Condition) Valid() (err error) { } /* -Evaluate uses the Evaluator closure function to apply the value (x) +Evaluate uses the [Evaluator] closure function to apply the value (x) to the receiver in order to conduct a matching/assertion test or analysis for some reason. This is entirely up to the user. -A Boolean value returned indicative of the result. Note that if an -instance of Evaluator was not assigned to the Condition prior to +An expression value is returned alongside an error. Note that if an +instance of [Evaluator] was not assigned to the [Condition] prior to execution of this method, the return value shall always be false. */ func (r Condition) Evaluate(x ...any) (ev any, err error) { @@ -630,8 +631,9 @@ func (r Condition) Evaluate(x ...any) (ev any, err error) { } /* -SetEvaluator assigns the instance of Evaluator to the receiver. This -will allow the Evaluate method to return a more meaningful result. +SetEvaluator assigns the instance of [Evaluator] to the receiver. This +will allow the [Condition.Evaluate] method to return a more meaningful +result. Specifying nil shall disable this capability if enabled. */ @@ -643,8 +645,9 @@ func (r Condition) SetEvaluator(x Evaluator) Condition { } /* -SetValidityPolicy assigns the instance of ValidityPolicy to the receiver. -This will allow the Valid method to return a more meaningful result. +SetValidityPolicy assigns the instance of [ValidityPolicy] to the receiver. +This will allow the [Condition.Valid] method to return a more meaningful +result. Specifying nil shall disable this capability if enabled. */ @@ -657,9 +660,9 @@ func (r Condition) SetValidityPolicy(x ValidityPolicy) Condition { } /* -SetPresentationPolicy assigns the instance of PresentationPolicy to the receiver. +SetPresentationPolicy assigns the instance of [PresentationPolicy] to the receiver. This will allow the user to leverage their own "stringer" method for automatic -use when this type's String method is called. +use when the [Condition.String] method is called. Specifying nil shall disable this capability if enabled. */ @@ -681,7 +684,7 @@ An instance of []string with two (2) values will be used for L and R encapsulation using the first and second slice values respectively. An instance of []string with only one (1) value is identical to the act of -providing a single string value, in that both L and R will use one value. +providing a single string value, in that both L and R will use the one value. */ func (r Condition) Encap(x ...any) Condition { if r.IsInit() { @@ -707,10 +710,10 @@ func (r *condition) getEncap() [][]string { /* NoNesting sets the no-nesting bit within the receiver. If -set to true, the receiver shall ignore any Stack or Stack -type alias instance when assigned using the SetExpression -method. In such a case, only primitives, etc., shall be -honored during the SetExpression operation. +set to true, the receiver shall ignore any [Stack] or [Stack] +type alias instance when assigned using the [Condition.SetExpression] +method. In such a case, only primitives, etc., shall be honored during +the [Condition.SetExpression] operation. A Boolean input value explicitly sets the bit as intended. Execution without a Boolean input value will *TOGGLE* the @@ -724,10 +727,10 @@ func (r Condition) NoNesting(state ...bool) Condition { /* CanNest returns a Boolean value indicative of whether -the no-nesting bit is unset, thereby allowing a Stack -or Stack type alias instance to be set as the value. +the no-nesting bit is unset, thereby allowing a [Stack] +or [Stack] type alias instance to be set as the value. -See also the IsNesting method. +See also the [Condition.IsNesting] method. */ func (r Condition) CanNest() (can bool) { if r.IsInit() { @@ -738,7 +741,7 @@ func (r Condition) CanNest() (can bool) { /* IsNesting returns a Boolean value indicative of whether the -underlying expression value is either a Stack or Stack type +underlying expression value is either a [Stack] or [Stack] type alias. If true, this indicates the expression value descends into another hierarchical (nested) context. */ @@ -761,13 +764,13 @@ func (r condition) isNesting() bool { /* IsFIFO returns a Boolean value indicative of whether the underlying -receiver instance's Expression value represents a Stack (or Stack -type alias) instance which exhibits First-In-First-Out behavior as -it pertains to the act of appending and truncating the receiver's -slices. +receiver instance's [Condition.Expression] value represents a [Stack] +(or [Stack] type alias) instance which exhibits First-In-First-Out +behavior as it pertains to the act of appending and truncating the +receiver's slices. -A value of false implies that no such Stack instance is set as the -expression, OR that the Stack exhibits Last-In-Last-Out behavior, +A value of false implies that no such [Stack] instance is set as the +expression, OR that the [Stack] exhibits Last-In-Last-Out behavior, which is the default ingress/egress scheme imposed upon instances of this type. */ @@ -796,7 +799,7 @@ expression within the receiver. The receiver shall undergo parenthetical encapsulation ( (...) ) during the string representation process. Individual string values shall not be encapsulated in parenthesis, only the whole (current) -stack. +[Stack] instance. A Boolean input value explicitly sets the bit as intended. Execution without a Boolean input value will *TOGGLE* the @@ -893,7 +896,7 @@ func (r Condition) Expression() (ex any) { } /* -Operator returns the Operator interface type instance found within the +Operator returns the [Operator] interface type instance found within the receiver. */ func (r Condition) Operator() (op Operator) { @@ -920,12 +923,12 @@ of the receiver instance. It will only function if the receiver is in good standing, and passes validity checks. Note that if the underlying expression value is not a known type, -such as a Stack or a Go primitive, this method may be uncertain +such as a [Stack] or a Go primitive, this method may be uncertain as to what it should do. A bogus string may be returned. In such a case, it may be necessary to subvert the default string representation behavior demonstrated by instances of this type in -favor of a custom instance of the PresentationPolicy closure type +favor of a custom instance of the [PresentationPolicy] closure type for maximum control. */ func (r Condition) String() (s string) { diff --git a/cond_test.go b/cond_test.go index 03fd932..6bf800f 100644 --- a/cond_test.go +++ b/cond_test.go @@ -883,4 +883,3 @@ func TestCondition_codecov(t *testing.T) { t.Errorf("%s failed: %T->%T conversion failure", t.Name(), cx, Cx) } } - diff --git a/fcf.go b/fcf.go index 0b5312a..2547d95 100644 --- a/fcf.go +++ b/fcf.go @@ -8,7 +8,7 @@ interface definitions. /* Evaluator is a first-class function signature type which may be leveraged by users in order to compose matching functions -by which a given Condition shall be measured/compared, etc. +by which a given [Condition] shall be measured/compared, etc. In other words, this type takes this package one step forward: it no longer merely creates various expressions in the abstract @@ -30,27 +30,27 @@ type Evaluator func(...any) (any, error) /* PushPolicy is a first-class (closure) function signature that may be leveraged by users in order to control what -types instances may be pushed into a Stack instance when -using its 'Push' method. +types instances may be pushed into a [Stack] instance when +using its [Stack.Push] method. When authoring functions or methods that conform to this signature, the idea is to return true for any value that should be pushed, and false for all others. This allows for an opportunity to interdict potentially undesirable -Stack additions, unsupported types, etc. +[Stack] additions, unsupported types, etc. -A PushPolicy function or method is executed for each -element being added to a Stack via its Push method. +A PushPolicy function or method is executed for each element +being added to a [Stack] via its [Stack.Push] method. */ type PushPolicy func(...any) error /* ValidityPolicy is a first-class (closure) function signature that may be leveraged by users in order to better gauge the -validity of a stack based on its configuration and/or values. +validity of a [Stack] based on its configuration and/or values. -A ValidityPolicy function or method is executed via the Stack -method Valid. +A ValidityPolicy function or method is executed via the +[Stack.Valid] method. */ type ValidityPolicy func(...any) error @@ -62,7 +62,7 @@ one may write their own "stringer" (String()) function or method and use it to override the default behavior of the package based String method(s). -Note that basic Stack instances are ineligible for the process of +Note that basic [Stack] instances are ineligible for the process of string representation, thus no PresentationPolicy may be set. */ type PresentationPolicy func(...any) string diff --git a/log.go b/log.go index b953b69..5433ab5 100644 --- a/log.go +++ b/log.go @@ -1,7 +1,6 @@ package stackage import ( - //"encoding/json" "io" "log" "os" @@ -29,18 +28,6 @@ type logSystem struct { log *log.Logger } -/* -LogLevel is a uint16 type alias used to define compound logging -verbosity configuration values. - -LogLevel consts zero (0) through four (4) are as follows: - - - NoLogLevels defines the lack of any logging level - - LogLevel1 defines basic function and method call event logging - - LogLevel2 defines the logging of events relating to configuration state changes - - LogLevel3 - - LogLevel4 -*/ type LogLevel uint16 const NoLogLevels LogLevel = 0 // silent @@ -286,13 +273,13 @@ func newLogSystem(logger any, l ...any) (lsys *logSystem) { /* SetDefaultConditionLogger is a package-level function that will define -which logging facility new instances of Condition or equivalent type +which logging facility new instances of [Condition] or equivalent type alias shall be assigned during initialization procedures. Logging is available but is set to discard all events by default. Note that enabling this will have no effect on instances already created. -An active logging subsystem within any given Condition shall supercede +An active logging subsystem within any given [Condition] shall supercede this default package logger. The following types/values are permitted: @@ -303,12 +290,12 @@ The following types/values are permitted: - int: 0 will turn logging off - int: 1 will set basic STDOUT logging - int: 2 will set basic STDERR logging - - *log.Logger: user-defined *log.Logger instance will be set + - *[log.Logger]: user-defined *[log.Logger] instance will be set Case is not significant in the string matching process. -Logging may also be set for individual Condition instances using the -SetLogger method. Similar semantics apply. +Logging may also be set for individual [Condition] instances using the +[Condition.SetLogger] method. Similar semantics apply. */ func SetDefaultConditionLogger(logger any) { cLogDefault = resolveLogger(logger) @@ -319,7 +306,7 @@ func DefaultConditionLogLevel() int { } /* -SetDefaultConditionLogLevel sets the instance of LogLevel (lvl) +SetDefaultConditionLogLevel sets the instance of [LogLevel] (lvl) as a LITERAL value, as the verbosity indicator. When set with appropriate level identifiers, this will increase or decrease log verbosity accordingly. This value shall be used for logging @@ -327,10 +314,10 @@ verbosity (or lack thereof) for any newly created (and qualified) instances. Note that the input value(s) are NOT shifted. Users are expected -to either sum the values and cast the product as a LogLevel, OR -settle for one of the predefined LogLevel constants. +to either sum the values and cast the product as a [LogLevel], OR +settle for one of the predefined [LogLevel] constants. -The default is NoLogLevels, which implies a loglevel of zero (0). +The default is [NoLogLevels], which implies a loglevel of zero (0). */ func SetDefaultConditionLogLevel(lvl any) { var level LogLevel @@ -355,14 +342,14 @@ func SetDefaultConditionLogLevel(lvl any) { /* SetDefaultStackLogger is a package-level function that will define -which logging facility new instances of Stack or equivalent type +which logging facility new instances of [Stack] or equivalent type alias shall be assigned during initialization procedures. Logging is available but is set to discard all events by default. Note that enabling this will have no effect on instances already created. -An active logging subsystem within any given Stack shall supercede +An active logging subsystem within any given [Stack] shall supersede this default package logger. The following types/values are permitted: @@ -377,8 +364,8 @@ The following types/values are permitted: Case is not significant in the string matching process. -Logging may also be set for individual Stack instances using the -SetLogger method. Similar semantics apply. +Logging may also be set for individual [Stack] instances using the +[Stack.SetLogger] method. Similar semantics apply. */ func SetDefaultStackLogger(logger any) { sLogDefault = resolveLogger(logger) @@ -389,7 +376,7 @@ func DefaultStackLogLevel() int { } /* -SetDefaultStackLogLevel sets the instance of LogLevel (lvl) +SetDefaultStackLogLevel sets the instance of [LogLevel] (lvl) as a LITERAL value, as the verbosity indicator. When set with appropriate level identifiers, this will increase or decrease log verbosity accordingly. This value shall be used for logging @@ -397,10 +384,10 @@ verbosity (or lack thereof) for any newly created (and qualified) instances. Note that the input value(s) are NOT shifted. Users are expected -to either sum the values and cast the product as a LogLevel, OR -settle for one of the predefined LogLevel constants. +to either sum the values and cast the product as a [LogLevel], OR +settle for one of the predefined [LogLevel] constants. -The default is NoLogLevels, which implies a loglevel of zero +The default is [NoLogLevels], which implies a loglevel of zero (0). */ func SetDefaultStackLogLevel(lvl any) { @@ -481,123 +468,14 @@ func logDiscard(logger *log.Logger) (is bool) { } /* -Message is an optional type for use when a user-supplied Message channel has -been initialized and provided to one (1) or more Stack or Condition instances. - -Instances of this type shall contain diagnostic, error and debug information -pertaining to current operations of the given Stack or Condition instance. -*/ -/* -type Message struct { - ID string `json:"id"` - Msg string `json:"txt"` - Tag string `json:"tag"` - Type string `json:"type"` - Addr string `json:"addr,omitempty"` - Time string `json:"time"` // YYYYMMDDhhmmss.nnnnnnnnn - Len int `json:"len"` - Cap int `json:"max_len"` - Data map[string]string `json:"data,omitempty"` - PPol PresentationPolicy `json:"-"` -} - -func (r *Message) setText(txt any) (ok bool) { - r.Msg = sprintf("Unidentified or zero debug payload (%T)", txt) - - switch tv := txt.(type) { - case error: - if ok = tv != nil; ok { - r.Msg = tv.Error() - } - case string: - if ok = len(tv) != 0; ok { - r.Msg = tv - } - } - - return -} -*/ - -/* -String is a stringer method that returns the string representation of -the receiver instance. By default, this method returns JSON content. - -Instances of this type are used for the logging subsystem only, and do -not serve any purpose elsewhere. Use of the logging system as a whole -is entirely optional. - -Users may author their own stringer method by way of the PresentationPolicy -closure type and override the string representation procedure for instances -of this type (thus implementing any syntax or format they wish, i.e.: XML, -YAML, et al). -*/ -/* -func (r Message) String() (data string) { - if r.PPol != nil { - data = r.PPol() - return - } - - if r.Valid() { - if b, err := json.Marshal(&r); err == nil { - var replacements [][]string = [][]string{ - {`\\u`, `\u`}, - {``, `nil`}, - {` <= `, ` LE `}, - {` >= `, ` GE `}, - {` < `, ` LT `}, - {` > `, ` GT `}, - {`&&`, `SYMBOLIC_AND`}, - {`&`, `AMPERSAND`}, - {`||`, `SYMBOLIC_OR`}, - } - - data = string(b) - for _, repl := range replacements { - if str, err := uq(rplc(qt(data), repl[0], repl[1])); err == nil { - data = string(json.RawMessage(str)) - } - } - } - } - - return -} -*/ - -/* -Valid returns a Boolean value indicative of whether the receiver -is perceived to be valid. -*/ -/* -func (r Message) Valid() bool { - return (r.Type != `UNKNOWN` && - len(r.Time) > 0 && - len(r.Msg) > 0 && - len(r.Tag) > 0) -} -*/ - -/* -func getLogID(elem string) (id string) { - id = `no_identifier` - if _id := elem; len(_id) > 0 { - id = elem - } - return -} -*/ - -/* -Logger returns the *log.Logger instance. This can be used for quick -access to the log.Logger type's methods in a manner such as: +Logger returns the *[log.Logger] instance. This can be used for quick +access to the [log.Logger] type's methods in a manner such as: r.Logger().Fatalf("We died") It is not recommended to modify the return instance for the purpose -of disabling logging outright (see Stack.SetLogger method as well -as the SetDefaultStackLogger package-level function for ways of +of disabling logging outright (see [Stack.SetLogger] method as well +as the [SetDefaultStackLogger] package-level function for ways of doing this easily). */ func (r Stack) Logger() (l *log.Logger) { @@ -614,14 +492,14 @@ func (r *stack) logger() *log.Logger { } /* -Logger returns the *log.Logger instance. This can be used for quick -access to the log.Logger type's methods in a manner such as: +Logger returns the *[log.Logger] instance. This can be used for quick +access to the [log.Logger] type's methods in a manner such as: r.Logger().Fatalf("We died") It is not recommended to modify the return instance for the purpose -of disabling logging outright (see Stack.SetLogger method as well -as the SetDefaultConditionLogger package-level function for ways of +of disabling logging outright (see [Condition.SetLogger] method as well +as the [SetDefaultConditionLogger] package-level function for ways of doing this easily). */ func (r Condition) Logger() (l *log.Logger) { diff --git a/misc.go b/misc.go index f37bddb..324aedf 100644 --- a/misc.go +++ b/misc.go @@ -33,6 +33,7 @@ var ( split func(string, string) []string = strings.Split trimS func(string) string = strings.TrimSpace join func([]string, string) string = strings.Join + scmp func(string, string) int = strings.Compare now func() time.Time = time.Now ) @@ -484,13 +485,13 @@ func intStringer(x any) (s string) { Interface is an interface type qualified through instances of the following types (whether native, or type-aliased): - - Stack - - Condition + - [Stack] + - [Condition] This interface type offers users an alternative to the tedium of -repeated type assertion for every Stack and Condition instance they +repeated type assertion for every [Stack] and [Condition] instance they encounter. This may be particularly useful in situations where the -act of traversal is conducted upon a Stack instance that contains +act of traversal is conducted upon a [Stack] instance that contains myriad hierarchies and nested contexts of varying types. This is not a complete "replacement" for the explicit use of package diff --git a/op.go b/op.go index 5a1e969..6eaffb5 100644 --- a/op.go +++ b/op.go @@ -9,8 +9,8 @@ a whole. /* Operator is an interface type that allows user-defined operators to be used within instances -of Condition. In rare cases, users may wish to utilize operators that go beyond the package -provided ComparisonOperator definitions (or just represent the same operators in a different +of [Condition]. In rare cases, users may wish to utilize operators that go beyond the package +provided [ComparisonOperator] definitions (or just represent the same operators in a different way). Defining types that conform to the signature of this interface type allows just that. */ type Operator interface { @@ -62,7 +62,7 @@ operators: - Less Than Or Equal (<=) - Greater Than Or Equal (>=) -Instances of this type should be passed to Cond as the 'op' value. +Instances of this type should be passed to [Cond] as the 'op' value. */ type ComparisonOperator uint8 diff --git a/stack.go b/stack.go index b81c188..49ba90c 100644 --- a/stack.go +++ b/stack.go @@ -11,53 +11,54 @@ type Stack struct { /* stack represents the underlying ordered slice type, which -is embedded (in pointer form) within instances of Stack. +is embedded (in pointer form) within instances of [Stack]. */ type stack []any /* -List initializes and returns a new instance of Stack -configured as a simple list. Stack instances of this -design can be delimited using the SetDelimiter method. +List initializes and returns a new instance of [Stack] +configured as a simple list. [Stack] instances of this +design can be delimited using the [Stack.SetDelimiter] +method. */ func List(capacity ...int) Stack { return Stack{newStack(list, false, capacity...)} } /* -And initializes and returns a new instance of Stack -configured as a Boolean ANDed stack. +And initializes and returns a new instance of [Stack] +configured as a Boolean [And] stack. */ func And(capacity ...int) Stack { return Stack{newStack(and, false, capacity...)} } /* -Or initializes and returns a new instance of Stack -configured as a Boolean ORed stack. +Or initializes and returns a new instance of [Stack] +configured as a Boolean [Or] stack. */ func Or(capacity ...int) Stack { return Stack{newStack(or, false, capacity...)} } /* -Not initializes and returns a new instance of Stack -configured as a Boolean NOTed stack. +Not initializes and returns a new instance of [Stack] +configured as a Boolean [Not] stack. */ func Not(capacity ...int) Stack { return Stack{newStack(not, false, capacity...)} } /* -Basic initializes and returns a new instance of Stack, set +Basic initializes and returns a new instance of [Stack], set for basic operation only. Please note that instances of this design are not eligible for string representation, value encaps, delimitation, and other presentation-related string methods. As such, a zero -string (“) shall be returned should String() be executed. +string (“) shall be returned should [Stack.String] be executed. -PresentationPolicy instances cannot be assigned to Stack +[PresentationPolicy] instances cannot be assigned to [Stack] instances of this design. */ func Basic(capacity ...int) Stack { @@ -68,13 +69,13 @@ func Basic(capacity ...int) Stack { newStack initializes a new instance of *stack, configured with the kind (t) requested by the user. This function should only be executed when creating new instances of -Stack (or a Stack type alias), which embeds the *stack +[Stack](or a [Stack] type alias), which embeds the *stack type instance. */ func newStack(t stackType, fifo bool, c ...int) *stack { var ( - cfg *nodeConfig = new(nodeConfig) - st stack + cfg *nodeConfig = new(nodeConfig) + st stack ) cfg.log = newLogSystem(sLogDefault) @@ -107,14 +108,14 @@ func (r Stack) IsZero() bool { } /* -isZero is a private method called by Stack.IsZero. +isZero is a private method called by [Stack.IsZero]. */ func (r *stack) isZero() bool { return r == nil } /* -SetLogLevel enables the specified LogLevel instance(s), thereby +SetLogLevel enables the specified [LogLevel] instance(s), thereby instructing the logging subsystem to accept events for submission and transcription to the underlying logger. @@ -133,7 +134,7 @@ func (r Stack) SetLogLevel(l ...any) Stack { /* LogLevels returns the string representation of a comma-delimited list -of all active LogLevel values within the receiver. +of all active [LogLevel] values within the receiver. */ func (r Stack) LogLevels() string { cfg, _ := r.config() @@ -141,7 +142,7 @@ func (r Stack) LogLevels() string { } /* -UnsetLogLevel disables the specified LogLevel instance(s), thereby +UnsetLogLevel disables the specified [LogLevel] instance(s), thereby instructing the logging subsystem to discard events submitted for transcription to the underlying logger. */ @@ -152,11 +153,10 @@ func (r Stack) UnsetLogLevel(l ...any) Stack { } /* -Addr returns the string representation of the pointer -address for the receiver. This may be useful for logging -or debugging operations. +Addr returns the string representation of the pointer address for the +receiver. This may be useful for logging or debugging operations. -Note: this call uses fmt.Sprintf. +Note: this call uses [fmt.Sprintf]. */ func (r Stack) Addr() string { return ptrString(r.stack) @@ -170,12 +170,142 @@ func ptrString(x any) (addr string) { return } +/* +Less returns a Boolean value indicative of whether the slice at index +i is deemed to be less than the slice at j in the context of ordering. + +This method is intended to satisfy the func(int,int) bool signature +required by [sort.Interface]. + +See also [Stack.SetLessFunc] method for a means of specifying instances +of this function. + +If no custom closure was assigned, the package-default closure is used, +which evaluates the string representation of values in order to conduct +alphabetical sorting. This means that both i and j must reference slice +values in one of the following states: + + - Type of slice instance must have its own String method + - Value is a go primitive, such as a string or int + +Equal values return false, as do zero string values. +*/ +func (r Stack) Less(i, j int) (less bool) { + if r.IsInit() { + cfg, _ := r.stack.config() + if meth := cfg.lss; meth != nil { + less = meth(i, j) + } else { + less = r.stack.defaultLesser(i, j) + } + } + + return +} + +func (r stack) defaultLesser(idx1, idx2 int) bool { + slice1, _, _ := r.index(idx1) + slice2, _, _ := r.index(idx2) + + var strs []string = make([]string, 2) + for idx, slice := range []any{ + slice1, + slice2, + } { + if slice != nil { + var ok bool + if strs[idx], ok = slice.(string); !ok { + if meth := getStringer(slice); meth != nil { + strs[idx] = meth() + } else if isKnownPrimitive(slice) { + strs[idx] = primitiveStringer(slice) + } + } + + if strs[idx] == `` { + return false + } + } + } + + switch scmp(strs[0], strs[1]) { + case -1: + return true + } + + return false +} + +/* +SetLessFunc assigns the provided closure instance to the receiver instance, +thereby allowing effective use of the [Stack.Less] method. + +If a nil value, or no values, are submitted, the package-default sorting +mechanism will take precedence. +*/ +func (r Stack) SetLessFunc(function ...func(int, int) bool) Stack { + if r.IsInit() { + r.stack.setLessFunc(function...) + } + + return r +} + +func (r *stack) setLessFunc(function ...func(int, int) bool) { + var funk func(int, int) bool + if len(function) > 0 { + if function[0] == nil { + funk = r.defaultLesser + } else { + funk = function[0] + } + } else { + funk = r.defaultLesser + } + + if !r.positive(ronly) { + cfg, _ := r.config() + cfg.lss = funk + } + + return +} + +/* +Swap implements the func(int,int) signature required by the [sort.Interface] +signature. See also the [Stack.SetSwapFunc] method for a means of specifying +user-authored instances of this function. +*/ +func (r Stack) Swap(i, j int) { + if r.IsInit() { + r.stack.swap(i, j) + } +} + +func (r *stack) swap(i, j int) { + if !r.positive(ronly) { + if ok := i <= r.ulen(); !ok { + return + } else if ok = j <= r.ulen(); !ok { + return + } + + i++ + j++ + + r.lock() + defer r.unlock() + + (*r)[i], (*r)[j] = (*r)[j], (*r)[i] + } +} + /* SetAuxiliary assigns aux, as initialized and optionally populated as needed by the user, to the receiver instance. The aux input value may be nil. -If no variadic input is provided, the default Auxiliary allocation +If no variadic input is provided, the default [Auxiliary] allocation shall occur. Note that this method shall obliterate any instance that may already @@ -189,7 +319,7 @@ func (r Stack) SetAuxiliary(aux ...Auxiliary) Stack { } /* -setAuxiliary is a private method called by Stack.SetAuxiliary. +setAuxiliary is a private method called by [Stack.SetAuxiliary]. */ func (r *stack) setAuxiliary(aux ...Auxiliary) { cfg, _ := r.config() @@ -209,7 +339,7 @@ func (r *stack) setAuxiliary(aux ...Auxiliary) { } /* -Auxiliary returns the instance of Auxiliary from within the receiver. +Auxiliary returns the instance of [Auxiliary] from within the receiver. */ func (r Stack) Auxiliary() (aux Auxiliary) { if r.IsInit() { @@ -219,7 +349,7 @@ func (r Stack) Auxiliary() (aux Auxiliary) { } /* -auxiliary is a private method called by Stack.Auxiliary. +auxiliary is a private method called by [Stack.Auxiliary]. */ func (r stack) auxiliary() (aux Auxiliary) { sc, _ := r.config() @@ -245,7 +375,7 @@ func (r Stack) IsFIFO() (is bool) { } /* -isFIFO is a private method called by the Stack.IsFIFO method, et al. +isFIFO is a private method called by the [Stack.IsFIFO] method, et al. */ func (r stack) isFIFO() bool { sc, _ := r.config() @@ -262,8 +392,9 @@ to be honored. - A value of false (the default) shall impose Last-In-First-Out behavior This setting shall impose no influence on any methods other than -the Pop method. In other words, Push, Defrag, Remove, Replace, et -al., will all operate in the same manner regardless. +the [Stack.Pop] method. In other words, [Stack.Push], [Stack.Defrag], +[Stack.Remove], [Stack.Replace], et al., will all operate in the same +manner regardless. Once set to the non-default value of true, this setting cannot be changed nor toggled ever again for this instance and shall not be @@ -356,7 +487,7 @@ func (r stack) kind() string { Valid returns an error if the receiver lacks a configuration value, or is unset as a whole. This method does not check to see whether the receiver is in an error condition regarding -user content operations (see the E method). +user content operations (see the [Stack.Err] method). */ func (r Stack) Valid() (err error) { if r.stack == nil { @@ -369,7 +500,7 @@ func (r Stack) Valid() (err error) { } /* -valid is a private method called by Stack.Valid. +valid is a private method called by [Stack.Valid]. */ func (r *stack) valid() (is bool) { if r.isInit() { @@ -392,11 +523,11 @@ IsInit returns a Boolean value indicative of whether the receiver has been initialized using any of the following package-level functions: - - And - - Or - - Not - - List - - Basic + - [And] + - [Or] + - [Not] + - [List] + - [Basic] This method does not take into account the presence (or absence) of any user-provided values (e.g.: a length of @@ -410,7 +541,7 @@ func (r Stack) IsInit() (is bool) { } /* -isInit is a private method called by Stack.IsInit. +isInit is a private method called by [Stack.IsInit]. */ func (r *stack) isInit() bool { //var err error @@ -435,12 +566,12 @@ The following types/values are permitted: - int: 0 will turn logging off - int: 1 will set basic STDOUT logging - int: 2 will set basic STDERR logging - - *log.Logger: user-defined *log.Logger instance will be set; it should not be nil + - *[log.Logger]: user-defined *[log.Logger] instance will be set; it should not be nil Case is not significant in the string matching process. -Logging may also be set globally using the SetDefaultLogger -package level function. Similar semantics apply. +Logging may also be set globally using the [SetDefaultLogger] package-level +function. Similar semantics apply. */ func (r Stack) SetLogger(logger any) Stack { if r.IsInit() { @@ -463,8 +594,8 @@ The following circumstances will result in a false return: The receiver instance (r) is not modified in any way as a result of calling this method. If the receiver (source) should -undergo a call to its Reset() method following a call to the -Transfer method, only the source will be emptied, and of the +undergo a call to its [Stack.Reset] method following a call to the +[Stack.Transfer] method, only the source will be emptied, and of the slices that have since been transferred instance shall remain in the destination instance. */ @@ -476,7 +607,7 @@ func (r Stack) Transfer(dest Stack) (ok bool) { } /* -transfer is a private method executed by the Stack.Transfer +transfer is a private method executed by the [Stack.Transfer] method. It will return a *stack instance containing the same slices as the receiver (r). Configuration is not copied, nor is a destination *stack subject to initialization within this @@ -570,7 +701,7 @@ func (r Stack) Insert(x any, left int) (ok bool) { } /* -insert is a private method called by Stack.Insert. +insert is a private method called by [Stack.Insert]. */ func (r *stack) insert(x any, left int) (ok bool) { // note the len before we start @@ -643,7 +774,7 @@ func (r Stack) Reset() { } /* -reset is a private method called by Stack.Reset. +reset is a private method called by [Stack.Reset]. */ func (r *stack) reset() { if !r.positive(ronly) { @@ -676,7 +807,7 @@ func (r Stack) Remove(idx int) (slice any, ok bool) { } /* -remove is a private method called by Stack.Remove. +remove is a private method called by [Stack.Remove]. */ func (r *stack) remove(idx int) (slice any, ok bool) { @@ -737,7 +868,7 @@ func (r Stack) Paren(state ...bool) Stack { /* IsNesting returns a Boolean value indicative of whether -at least one (1) slice member is either a Stack or Stack +at least one (1) slice member is either a [Stack] or [Stack] type alias. If true, this indicates the relevant slice descends into another hierarchical (nested) context. */ @@ -750,14 +881,14 @@ func (r Stack) IsNesting() (is bool) { } /* -isNesting is a private method called by Stack.IsNesting. +isNesting is a private method called by [Stack.IsNesting]. When called, this method returns a Boolean value indicative of whether the receiver contains one (1) or more slice elements that match either of the following conditions: - - Slice type is a stackage.Stack native type instance, OR ... - - Slice type is a stackage.Stack type-aliased instance + - Slice type is a [Stack] native type instance, OR ... + - Slice type is a [Stack] type-aliased instance A return value of true is thrown at the first of either occurrence. Length of matched candidates is not significant @@ -806,7 +937,7 @@ func (r Stack) IsParen() bool { } /* -Stack will fold the case of logical Boolean operators which +Fold will fold the case of logical Boolean operators which are not represented through symbols. For example, `AND` becomes `and`, or vice versa. This won't have any effect on List-based receivers, or if symbols are used in place @@ -823,9 +954,9 @@ func (r Stack) Fold(state ...bool) Stack { } /* -NegativeIndices will enable negative index support when -using the Index method extended by this type. See the -method documentation for further details. +NegativeIndices will enable negative index support when using +the [Stack.Index] method extended by this type. See the method +documentation for further details. A Boolean input value explicitly sets the bit as intended. Execution without a Boolean input value will *TOGGLE* the @@ -839,7 +970,7 @@ func (r Stack) NegativeIndices(state ...bool) Stack { /* ForwardIndices will enable forward index support when using -the Index method extended by this type. See the method +the [Stack.Index] method extended by this type. See the method documentation for further details. A Boolean input value explicitly sets the bit as intended. @@ -854,7 +985,7 @@ func (r Stack) ForwardIndices(state ...bool) Stack { /* SetDelimiter accepts input characters (as string, or a single rune) for use -in controlled stack value joining when the underlying stack type is a LIST. +in controlled [Stack] value joining when the underlying [Stack] type is a LIST. In such a case, the input value shall be used for delimitation of all slice values during the string representation process. @@ -863,7 +994,7 @@ this value within the receiver. If this method is executed using any other stack type, the operation has no effect. If using Boolean AND, OR or NOT stacks and a character delimiter is -preferred over a Boolean WORD, see the Stack.Symbol method. +preferred over a Boolean WORD, see the [Stack.Symbol] method. */ func (r Stack) SetDelimiter(x any) Stack { if r.IsInit() { @@ -877,9 +1008,9 @@ func (r Stack) SetDelimiter(x any) Stack { /* assertListDelimiter is a private function called (indirectly) -by the Stack.SetDelimiter method for the purpose of handing +by the [Stack.SetDelimiter] method for the purpose of handing type assertion for values that may express a particular value -intended to serve as delimiter character for a LIST Stack when +intended to serve as delimiter character for a LIST [Stack] when string representation is requested. */ func assertListDelimiter(x any) (v string) { @@ -906,7 +1037,7 @@ func (r Stack) Delimiter() string { } /* -setListDelimiter is a private method called by Stack.SetDelimiter +setListDelimiter is a private method called by [Stack.SetDelimiter] */ func (r *stack) setListDelimiter(x any) { sc, _ := r.config() @@ -914,7 +1045,7 @@ func (r *stack) setListDelimiter(x any) { } /* -getListDelimiter is a private method called by Stack.Delimiter. +getListDelimiter is a private method called by [Stack.Delimiter]. */ func (r *stack) getListDelimiter() string { sc, _ := r.config() @@ -923,7 +1054,7 @@ func (r *stack) getListDelimiter() string { } /* -Encap accepts input characters for use in controlled stack value +Encap accepts input characters for use in controlled [Stack] value encapsulation. A single string value will be used for both L and R encapsulation. @@ -933,7 +1064,7 @@ encapsulation using the first and second slice values respectively. An instance of []string with only one (1) value is identical to the act of providing a single string value, in that both L and R will use -one (1) value. +the one value. */ func (r Stack) Encap(x ...any) Stack { if r.IsInit() { @@ -946,7 +1077,7 @@ func (r Stack) Encap(x ...any) Stack { } /* -setEncap is a private method called by Stack.Encap. +setEncap is a private method called by [Stack.Encap]. */ func (r *stack) setEncap(x ...any) { sc, _ := r.config() @@ -995,7 +1126,7 @@ func (r Stack) SetID(id string) Stack { } /* -setID is a private method called by Stack.SetID. +setID is a private method called by [Stack.SetID]. */ func (r *stack) setID(id string) { sc, _ := r.config() @@ -1026,7 +1157,7 @@ func (r Stack) SetCategory(cat string) Stack { } /* -setCat is a private method called by Stack.SetCategory. +setCat is a private method called by [Stack.SetCategory]. */ func (r *stack) setCat(cat string) { sc, _ := r.config() @@ -1045,7 +1176,7 @@ func (r Stack) Category() (cat string) { } /* -getCat is a private method called by Stack.Category. +getCat is a private method called by [Stack.Category]. */ func (r *stack) getCat() (cat string) { sc, _ := r.config() @@ -1066,7 +1197,7 @@ func (r Stack) ID() (id string) { } /* -getID is a private method called by Stack.ID. +getID is a private method called by [Stack.ID]. */ func (r *stack) getID() string { sc, _ := r.config() @@ -1106,20 +1237,20 @@ func (r Stack) NoPadding(state ...bool) Stack { /* NoNesting sets the no-nesting bit within the receiver. If -set to true, the receiver shall ignore any Stack or Stack -type alias instance when pushed using the Push method. In -such a case, only primitives, Conditions, etc., shall be -honored during the Push operation. +set to true, the receiver shall ignore any [Stack] or [Stack] +type alias instance when pushed using the [Stack.Push] method. +In such a case, only primitives, [Condition] instances, etc., +shall be honored during the [Stack.Push] operation. Note this will only have an effect when not using a custom -PushPolicy. When using a custom PushPolicy, the user has +[PushPolicy]. When using a custom [PushPolicy], the user has total control -- and full responsibility -- in deciding what may or may not be pushed. Also note that setting or unsetting this bit shall not, in -any way, have an impact on pre-existing Stack or Stack type +any way, have an impact on pre-existing [Stack] or [Stack] type alias instances within the receiver. This bit only has an -influence on the Push method and only when set to true. +influence on the [Stack.Push] method and only when set to true. A Boolean input value explicitly sets the bit as intended. Execution without a Boolean input value will *TOGGLE* the @@ -1133,10 +1264,10 @@ func (r Stack) NoNesting(state ...bool) Stack { /* CanNest returns a Boolean value indicative of whether -the no-nesting bit is unset, thereby allowing the Push -of Stack and/or Stack type alias instances. +the no-nesting bit is unset, thereby allowing the push +of [Stack] and/or [Stack] type alias instances. -See also the IsNesting method. +See also the [Stack.IsNesting] method. */ func (r Stack) CanNest() bool { return r.getState(nnest) @@ -1182,7 +1313,7 @@ Execution of this method with no arguments empty the symbol store within the receiver, thereby returning to the default word-based behavior. -This method has no effect on list-style stacks. +This method has no effect on list-style [Stack] instances. */ func (r Stack) Symbol(c ...any) Stack { if r.IsInit() { @@ -1206,7 +1337,7 @@ func (r Stack) Symbol(c ...any) Stack { } /* -setSymbol is a private method called by Stack.Symbol. +setSymbol is a private method called by [Stack.Symbol]. */ func (r *stack) setSymbol(sym string) { sc, _ := r.config() @@ -1322,10 +1453,10 @@ func (r stack) positive(x cfgFlag) bool { /* Mutex enables the receiver's mutual exclusion locking capabilities. -Subsequent calls of write-related methods, such as Push, Pop, Remove -and others, shall invoke MuTeX locking at the latest possible state -of processing, thereby minimizing the duration of a lock as much as -possible. +Subsequent calls of write-related methods, such as [Stack.Push], +[Stack.Pop], [Stack.Remove] and others, shall invoke MuTeX locking at +the latest possible state of processing, thereby minimizing the duration +of a lock. */ func (r Stack) Mutex() Stack { if r.IsInit() { @@ -1335,7 +1466,7 @@ func (r Stack) Mutex() Stack { } /* -setMutex is a private method called by Stack.Mutex. +setMutex is a private method called by [Stack.Mutex]. */ func (r *stack) setMutex() { sc, _ := r.config() @@ -1356,7 +1487,7 @@ func (r Stack) CanMutex() (can bool) { } /* -canMutex is a private method called by Stack.CanMutex. +canMutex is a private method called by [Stack.CanMutex]. */ func (r stack) canMutex() bool { sc, _ := r.config() @@ -1458,15 +1589,15 @@ the receiver. The return values shall be interpreted as follows: - A minus one (-1) value indicates infinite capacity is available; no limit is imposed */ func (r Stack) Cap() (c int) { - if r.IsInit() { - offset := -1 - c = offset - if _c := r.cap(); _c > 0 { - c = _c + offset // cfg.cap minus 1 - } - } + if r.IsInit() { + offset := -1 + c = offset + if _c := r.cap(); _c > 0 { + c = _c + offset // cfg.cap minus 1 + } + } - return + return } /* @@ -1522,11 +1653,11 @@ func (r Stack) Kind() (k string) { } /* -String is a stringer method that returns the string representation -of the receiver. +String is a stringer method that returns the string representation of +the receiver. -Note that invalid Stack instances, as well as basic Stacks, are not -eligible for string representation. +Note that invalid [Stack] instances, as well as basic [Stack] instances, +are not eligible for string representation. */ func (r Stack) String() (s string) { if r.IsInit() { @@ -1546,7 +1677,7 @@ func (r *stack) canString() (can bool, ot string, oc stackType) { } /* -string is a private method called by Stack.String. +string is a private method called by [Stack.String]. */ func (r *stack) string() (assembled string) { if can, ot, oc := r.canString(); can { @@ -1703,8 +1834,8 @@ a success-indicative Boolean value. The semantics of "traversability" are as follows: - - Any "nesting" instance must be a Stack or Stack type alias - - Condition instances must either be the final requested element, OR must contain a Stack or Stack type alias instance through which the traversal process may continue + - Any "nesting" instance must be a [Stack] or [Stack] type alias + - [Condition] instances must either be the final requested element, OR must contain a [Stack] or [Stack] type alias instance through which the traversal process may continue - All other value types are returned as-is If the traversal ended at any given value, it will be returned along with a @@ -1724,7 +1855,7 @@ func (r Stack) Traverse(indices ...int) (slice any, ok bool) { } /* -traverse is a private method called by Stack.Traverse. +traverse is a private method called by [Stack.Traverse]. */ func (r stack) traverse(indices ...int) (slice any, ok, done bool) { if r.valid() { @@ -1756,7 +1887,7 @@ func (r stack) traverse(indices ...int) (slice any, ok, done bool) { /* Reveal processes the receiver instance and disenvelops needlessly -enveloped Stack slices. +enveloped [Stack] slices. */ func (r Stack) Reveal() Stack { if r.IsInit() { @@ -1768,7 +1899,7 @@ func (r Stack) Reveal() Stack { } /* -reveal is a private method called by Stack.Reveal. +reveal is a private method called by [Stack.Reveal]. */ func (r *stack) reveal() (err error) { r.lock() @@ -1792,9 +1923,9 @@ func (r *stack) reveal() (err error) { /* revealDescend is a private method called by stack.reveal. It engages the second -level of processing of the provided inner Stack instance. +level of processing of the provided inner [Stack] instance. -Its first order of business is to determine the length of the inner Stack instance +Its first order of business is to determine the length of the inner [Stack] instance and take action based on the result: - A length of zero (0) results in the deletion of the provided inner stack (at the @@ -1852,12 +1983,12 @@ revealSingle is a private method called by stack.revealDescend. It engages the t level of processing of the receiver's slice instance found at the provided index (idx). An error is returned at the conclusion of processing. -If a single Condition or Condition type alias instance (whether pointer-based or not) +If a single [Condition] or [Condition] type alias instance (whether pointer-based or not) is found at the slice index indicated, its Expression value is checked for the presence -of a Stack or Stack type alias. If one is present, a new top-level stack.reveal recursion +of a [Stack] or [Stack] type alias. If one is present, a new top-level stack.reveal recursion is launched. -If, on the other hand, a Stack or Stack type alias (again, pointer or not) is found at +If, on the other hand, a [Stack] or [Stack] type alias (again, pointer or not) is found at the slice index indicates, a new top-level stack.reveal recursion is launched into it directly. */ @@ -1886,7 +2017,7 @@ func (r *stack) revealSingle(idx int) (err error) { /* traverseAssertionHandler handles the type assertion processes during traversal of one (1) or more -nested Stack/Stack alias instances that may or may not reside in Condition/Condition alias instances. +nested [Stack]/[Stack] alias instances that may or may not reside in [Condition]/[Condition] alias instances. */ func (r stack) traverseAssertionHandler(x any, idx int, indices ...int) (slice any, ok, done bool) { @@ -1916,7 +2047,7 @@ func (r stack) traverseAssertionHandler(x any, idx int, indices ...int) (slice a /* traverseStackInCondition is the private recursive helper method for the stack.traverse method. This -method will traverse either a Stack *OR* Stack alias type fashioned by the user that is the Condition +method will traverse either a [Stack] *OR* [Stack] alias type fashioned by the user that is the [Condition] instance's own value (i.e.: recurse stacks that reside in conditions, etc ...). */ func (r stack) traverseStackInCondition(u any, idx int, indices ...int) (slice any, ok, done bool) { @@ -1940,7 +2071,7 @@ func (r stack) traverseStackInCondition(u any, idx int, indices ...int) (slice a /* traverseStack is the private recursive helper method for the stack.traverse method. This -method will traverse either a Stack *OR* Stack alias type fashioned by the user. +method will traverse either a [Stack] *OR* [Stack] alias type fashioned by the user. */ func (r stack) traverseStack(u any, idx int, indices ...int) (slice any, ok, done bool) { if s, sOK := stackTypeAliasConverter(u); sOK { @@ -1968,21 +2099,21 @@ on the configuration of the receiver. Negatives: When negative index support is enabled, a negative index will not panic, rather the index number will be increased such that it -becomes positive and within the bounds of the stack length, and (perhaps +becomes positive and within the bounds of the [Stack] length, and (perhaps most importantly) aligned with the relative (intended) slice. To offer an example, -2 would return the second-to-last slice. When negative index support is NOT enabled, nil is returned for any index out of bounds along with a Boolean value of false, although no panic will occur. Positives: When forward index support is enabled, an index greater than -the length of the stack shall be reduced to the highest valid slice index. -For example, if an index of twenty (20) were used on a stack instance of +the length of the [Stack] shall be reduced to the highest valid slice index. +For example, if an index of twenty (20) were used on a [Stack] instance of a length of ten (10), the index would transform to nine (9). When forward index support is NOT enabled, nil is returned for any index out of bounds along with a Boolean value of false, although no panic will occur. -In any scenario, a valid index within the bounds of the stack's length -returns the intended slice along with Boolean value of true. +In any scenario, a valid index within the bounds of the [Stack] instance's +length returns the intended slice along with Boolean value of true. */ func (r Stack) Index(idx int) (slice any, ok bool) { if r.IsInit() { @@ -1992,7 +2123,7 @@ func (r Stack) Index(idx int) (slice any, ok bool) { } /* -index is a private method called by Stack.Index. +index is a private method called by [Stack.Index]. */ func (r stack) index(i int) (slice any, idx int, ok bool) { if L := r.ulen(); L > 0 { @@ -2096,7 +2227,7 @@ an actual slice value was found. The requisite slice shall be one (1) of the following, depending on ordering mode in effect: - - In the default mode -- LIFO -- this shall be the final slice (index "Stack.Len() - 1", or the "far right" element) + - In the default mode -- LIFO -- this shall be the final slice (index [Stack.Len] - 1", or the "far right" element) - In the alternative mode -- FIFO -- this shall be the first slice (index 0, or the "far left" element) Note that if the receiver is in an invalid state, or has a zero length, @@ -2113,7 +2244,7 @@ func (r Stack) Pop() (popped any, ok bool) { } /* -pop is a private method called by Stack.Pop. +pop is a private method called by [Stack.Pop]. */ func (r *stack) pop() (slice any, ok bool) { @@ -2145,12 +2276,12 @@ func (r *stack) pop() (slice any, ok bool) { } /* -Push appends the provided value(s) to the receiver, -and returns the receiver in fluent form. +Push appends the provided value(s) to the receiver, and returns the +receiver in fluent form. -Note that if the receiver is in an invalid state, or -if maximum capacity has been set and reached, each of -the values intended for append shall be ignored. +Note that if the receiver is in an invalid state, or if maximum capacity +has been set and reached, each of the values intended for append shall +be ignored. */ func (r Stack) Push(y ...any) Stack { if r.IsInit() { @@ -2162,7 +2293,7 @@ func (r Stack) Push(y ...any) Stack { } /* -push is a private method called by Stack.Push. +push is a private method called by [Stack.Push]. */ func (r *stack) push(x ...any) { @@ -2194,7 +2325,7 @@ func (r Stack) Reverse() Stack { } /* -reverse is a private niladic and void method called exclusively by Stack.Reverse. +reverse is a private niladic and void method called exclusively by [Stack.Reverse]. */ func (r *stack) reverse() { @@ -2229,16 +2360,16 @@ The max integer, which defaults to fifty (50) when unset, shall result in the sc when the number of nil slices encountered consecutively reaches the maximum. This is to prevent the process from looping into eternity. -If run on a Stack or Stack type-alias that is currently in possession of one (1) or more nested Stack -or Stack type-alias instances, Defrag shall hierarchically traverse the structure and process it no +If run on a [Stack] or [Stack] type-alias that is currently in possession of one (1) or more nested [Stack] +or [Stack] type-alias instances, Defrag shall hierarchically traverse the structure and process it no differently than the top-level instance. This applies to such Stack values nested with an instance of -Condition or Condition type-alias as well. +[Condition] or [Condition] type-alias as well. This is potentially a destructive method and is still very much considered EXPERIMENTAL. While all tests yield expected results, those who use this method are advised to exercise extreme caution. The most obvious note of caution pertains to the volatility of index numbers, which shall shift according -to the defragmentation's influence on the instance in question. By necessity, Len return values shall -also change accordingly. +to the defragmentation's influence on the instance in question. By necessity, [Stack.Len] return +values shall also change accordingly. */ func (r Stack) Defrag(max ...int) Stack { if r.IsInit() { @@ -2276,7 +2407,7 @@ func (r Stack) Defrag(max ...int) Stack { } /* -calculateDefragMax is a private function executed exclusively by Stack.Defrag, and +calculateDefragMax is a private function executed exclusively by [Stack.Defrag], and exists simply to keep cyclomatics factors <=9 in the caller. */ func calculateDefragMax(max ...int) (m int) { @@ -2422,7 +2553,7 @@ func (r Stack) CapReached() (cr bool) { } /* -capReached is a private method called by Stack.CapReached. +capReached is a private method called by [Stack.CapReached]. */ func (r stack) capReached() (rc bool) { if r.cap() == 0 { @@ -2450,10 +2581,10 @@ func (r *stack) genericAppend(x ...any) { } /* -SetPushPolicy assigns the provided PushPolicy closure function +SetPushPolicy assigns the provided [PushPolicy] closure function to the receiver, thereby enabling protection against undesired -appends to the Stack. The provided function shall be executed -by the Push method for each individual item being added. +appends to the [Stack]. The provided function shall be executed +by the [Stack.Push] method for each individual item being added. */ func (r Stack) SetPushPolicy(ppol PushPolicy) Stack { if r.IsInit() { @@ -2465,7 +2596,7 @@ func (r Stack) SetPushPolicy(ppol PushPolicy) Stack { } /* -setPushPolicy is a private method called by Stack.SetPushPolicy. +setPushPolicy is a private method called by [Stack.SetPushPolicy]. */ func (r *stack) setPushPolicy(ppol PushPolicy) *stack { sc, _ := r.config() @@ -2474,7 +2605,7 @@ func (r *stack) setPushPolicy(ppol PushPolicy) *stack { } /* -getPushPolicy is a private method called by Stack.Push. +getPushPolicy is a private method called by [Stack.Push]. */ func (r *stack) getPushPolicy() PushPolicy { sc, _ := r.config() @@ -2482,11 +2613,11 @@ func (r *stack) getPushPolicy() PushPolicy { } /* -SetPresentationPolicy assigns the provided PresentationPolicy +SetPresentationPolicy assigns the provided [PresentationPolicy] closure function to the receiver, thereby enabling full control -over the stringification of the receiver. Execution of this type's -String() method will execute the provided policy instead of the -package-provided routine. +over the stringification of the receiver. Execution of the +[Stack.String] method will execute the provided policy instead +of the package-provided routine. */ func (r Stack) SetPresentationPolicy(ppol PresentationPolicy) Stack { if r.IsInit() { @@ -2498,7 +2629,7 @@ func (r Stack) SetPresentationPolicy(ppol PresentationPolicy) Stack { } /* -setPresentationPolicy is a private method called by Stack.SetPresentationPolicy. +setPresentationPolicy is a private method called by [Stack.SetPresentationPolicy]. */ func (r *stack) setPresentationPolicy(ppol PresentationPolicy) *stack { @@ -2522,11 +2653,10 @@ func (r *stack) getPresentationPolicy() PresentationPolicy { } /* -SetValidityPolicy assigns the provided ValidityPolicy closure -function instance to the receiver, thereby allowing users to -introduce inline verification checks of a Stack to better -gauge its validity. The provided function shall be executed -by the Valid method. +SetValidityPolicy assigns the provided [ValidityPolicy] closure function +instance to the receiver, thereby allowing users to introduce inline +verification checks of a [Stack] to better gauge its validity. The provided +function shall be executed by the [Stack.Valid] method. */ func (r Stack) SetValidityPolicy(vpol ValidityPolicy) Stack { if r.IsInit() { @@ -2538,7 +2668,7 @@ func (r Stack) SetValidityPolicy(vpol ValidityPolicy) Stack { } /* -setValidityPolicy is a private method called by Stack.SetValidityPolicy. +setValidityPolicy is a private method called by [Stack.SetValidityPolicy]. */ func (r *stack) setValidityPolicy(vpol ValidityPolicy) *stack { sc, _ := r.config() @@ -2547,7 +2677,7 @@ func (r *stack) setValidityPolicy(vpol ValidityPolicy) *stack { } /* -getValidityPolicy is a private method called by Stack.Valid. +getValidityPolicy is a private method called by [Stack.Valid]. */ func (r *stack) getValidityPolicy() ValidityPolicy { sc, _ := r.config() diff --git a/stack_test.go b/stack_test.go index db5ddbd..b5cef44 100644 --- a/stack_test.go +++ b/stack_test.go @@ -6,6 +6,8 @@ import ( //"log" //"net/http" //_ "net/http/pprof" + "sort" + "strings" "testing" _ "time" ) @@ -84,6 +86,79 @@ func TestStackagePerf(t *testing.T) { } */ +/* +This example demonstrates basic support for stack sorting via the +[sort.Stable] method using basic string values. +*/ +func ExampleStack_String_withSort() { + var names Stack = List().SetDelimiter(' ') + names.Push(`Frank`, `Anna`, `Xavier`, `Betty`, `aly`, `Jim`, `fargus`) + sort.Stable(names) + fmt.Println(names) + // Output: Anna Betty Frank Jim Xavier aly fargus +} + +/* +This example demonstrates a simple "swapping" of indexed values by way +of the [Stack.Swap] method. +*/ +func ExampleStack_Swap() { + var names Stack = List().SetDelimiter(' ') + names.Push(`Frank`, `Anna`, `Xavier`, `Betty`, `aly`, `Jim`, `fargus`) + names.Swap(0, 5) + slice, _ := names.Index(0) + fmt.Println(slice) + // Output: Jim +} + +/* +This example demonstrates a simple order-based comparison using two +string values by way of the [Stack.Less] method. In this scenario, +a value of false is returned because "Frank" does not alphabetically +precede "Anna". + +Note that the semantics of [Stack.Less] apply, in that certain conditions +with regards to the values must be satified, else a custom Less closure +needs to be devised by the end-user. See the [Stack.SetLessFunc] method. +*/ +func ExampleStack_Less() { + var names Stack = List().SetDelimiter(' ') + names.Push(`Frank`, `Anna`, `Xavier`, `Betty`, `aly`, `Jim`, `fargus`) + fmt.Println(names.Less(0, 1)) + // Output: false +} + +/* +This example demonstrates custom stack sorting by way of a user-defined +closure set within the stack via the [Stack.SetLessFunc] value, thereby +allowing support with the [sort.Stable] method, et al. +*/ +func ExampleStack_SetLessFunc() { + var names Stack = List().SetDelimiter(' ') + names.Push(`Frank`, `Anna`, `Xavier`, `Betty`, `aly`, `Jim`, `fargus`) + + // Submit our custom closure + names.SetLessFunc(func(i, j int) bool { + // Note we are just presuming the values are + // strings merely for simplicity. Index and + // type checks should always be done in real + // life scenarios, else you risk panics, etc. + slice1, _ := names.Index(i) + slice2, _ := names.Index(j) + s1 := strings.ToLower(slice1.(string)) + s2 := strings.ToLower(slice2.(string)) + switch strings.Compare(s1, s2) { + case -1: + return true + } + return false + }) + + sort.Stable(names) + fmt.Println(names) + // Output: aly Anna Betty fargus Frank Jim Xavier +} + func ExampleComparisonOperator_Context() { var cop ComparisonOperator = Ge fmt.Printf("Context: %s", cop.Context()) @@ -1513,6 +1588,21 @@ func TestStack_codecov(t *testing.T) { s.SetLogger(1) s.SetLogger(sLogDefault) + s.Less(3, 6) + s.Less(6, 3) + s.Less(1, 2) + s.Swap(101, 48) + s.Swap(-1, 480) + s.Push( + customStack(List().Push(1, `&`)), + customStack(List().Push(`_n`, `?!?`, 5)), + ``) + sort.Stable(s) + s.Less(0, 1) + s.Less(0, 2) + s.SetLessFunc(nil) + s.SetLessFunc() + s.SetLogLevel(8, 16) s.UnsetLogLevel(8, 16)