@stdlib/dstructs-doubly-linked-list 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../lib/node.js", "../lib/main.js", "../lib/index.js"],
4
+ "sourcesContent": ["/**\n* @license Apache-2.0\n*\n* Copyright (c) 2018 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n// MODULES //\n\nvar defineProperty = require( '@stdlib/utils-define-property' );\n\n\n// MAIN //\n\n/**\n* List node constructor.\n*\n* @private\n* @constructor\n* @param {*} value - node value\n* @returns {Node} Node instance\n*\n* @example\n* var node = new Node( 'foo' );\n* // returns <Node>\n*/\nfunction Node( value ) { // eslint-disable-line stdlib/no-redeclare\n\t// Why getters? Because some of the list APIs will return the list \"node\", not the value. In which case, the node API is no longer private and we have to guard against users mucking about (deleting, updating, etc) with property values (in particular, the `next` and `prev` properties).\n\tdefineProperty( this, 'next', {\n\t\t'configurable': false,\n\t\t'enumerable': true,\n\t\t'get': function get() { // eslint-disable-line no-restricted-syntax\n\t\t\treturn this._next;\n\t\t}\n\t});\n\tdefineProperty( this, 'prev', {\n\t\t'configurable': false,\n\t\t'enumerable': true,\n\t\t'get': function get() { // eslint-disable-line no-restricted-syntax\n\t\t\treturn this._prev;\n\t\t}\n\t});\n\tthis.value = value;\n\n\tdefineProperty( this, '_next', {\n\t\t'configurable': false,\n\t\t'enumerable': false,\n\t\t'writable': true,\n\t\t'value': null\n\t});\n\tdefineProperty( this, '_prev', {\n\t\t'configurable': false,\n\t\t'enumerable': false,\n\t\t'writable': true,\n\t\t'value': null\n\t});\n\n\treturn this;\n}\n\n\n// EXPORTS //\n\nmodule.exports = Node;\n", "/**\n* @license Apache-2.0\n*\n* Copyright (c) 2018 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n/* eslint-disable no-restricted-syntax, no-invalid-this */\n\n'use strict';\n\n// MODULES //\n\nvar setReadOnly = require( '@stdlib/utils-define-nonenumerable-read-only-property' );\nvar setReadOnlyAccessor = require( '@stdlib/utils-define-nonenumerable-read-only-accessor' );\nvar iteratorSymbol = require( '@stdlib/symbol-iterator' );\nvar format = require( '@stdlib/string-format' );\nvar Node = require( './node.js' ); // eslint-disable-line stdlib/no-redeclare\n\n\n// MAIN //\n\n/**\n* Doubly linked list constructor.\n*\n* @constructor\n* @returns {DoublyLinkedList} linked list instance\n*\n* @example\n* var list = new DoublyLinkedList();\n*\n* // Add values to the list:\n* list.push( 'foo' ).push( 'bar' );\n*\n* // Remove the last value:\n* var v = list.pop();\n* // returns 'bar'\n*\n* // Add a new value to the list:\n* list.push( 'beep' );\n*\n* // Remove the first value:\n* v = list.shift();\n* // returns 'foo'\n*/\nfunction DoublyLinkedList() {\n\tif ( !(this instanceof DoublyLinkedList) ) {\n\t\treturn new DoublyLinkedList();\n\t}\n\tthis._length = 0;\n\tthis._first = null;\n\tthis._last = null;\n\treturn this;\n}\n\n/**\n* Clears the list.\n*\n* @name clear\n* @memberof DoublyLinkedList.prototype\n* @type {Function}\n* @returns {DoublyLinkedList} list instance\n*\n* @example\n* var list = new DoublyLinkedList();\n*\n* // Add values to the list:\n* list.push( 'foo' ).push( 'bar' );\n*\n* // Peek at the first value:\n* var v = list.first().value;\n* // returns 'foo'\n*\n* // Examine the list length:\n* var len = list.length;\n* // returns 2\n*\n* // Clear all list items:\n* list.clear();\n*\n* // Peek at the first value:\n* v = list.first();\n* // returns undefined\n*\n* // Examine the list length:\n* len = list.length;\n* // returns 0\n*/\nsetReadOnly( DoublyLinkedList.prototype, 'clear', function clear() {\n\tthis._length = 0;\n\tthis._first = null;\n\tthis._last = null;\n\treturn this;\n});\n\n/**\n* Returns the first list node.\n*\n* @name first\n* @memberof DoublyLinkedList.prototype\n* @type {Function}\n* @returns {(Node|void)} list node\n*\n* @example\n* var list = new DoublyLinkedList();\n*\n* // Add values to the list:\n* list.push( 'foo' ).push( 'bar' );\n*\n* // Peek at the first value:\n* var v = list.first().value;\n* // returns 'foo'\n*/\nsetReadOnly( DoublyLinkedList.prototype, 'first', function first() {\n\tif ( this._length ) {\n\t\treturn this._first;\n\t}\n});\n\n/**\n* Inserts a value into the list either before or after a provided list node.\n*\n* @name insert\n* @memberof DoublyLinkedList.prototype\n* @type {Function}\n* @param {Node} node - node after which to insert the value\n* @param {*} value - value to insert\n* @param {string} [location='after'] - location\n* @throws {Error} must provide a node belonging to the list\n* @throws {Error} must provide a recognized location\n* @returns {DoublyLinkedList} list instance\n*\n* @example\n* var list = new DoublyLinkedList();\n*\n* // Add values to the list:\n* list.push( 'foo' ).push( 'bar' ).push( 'beep' );\n*\n* // Determine the list length:\n* var len = list.length;\n* // returns 3\n*\n* // Get the second node:\n* var node = list.first().next;\n*\n* // Insert a value after the second node:\n* list.insert( node, 'boop' );\n*\n* // Determine the list length:\n* len = list.length;\n* // returns 4\n*/\nsetReadOnly( DoublyLinkedList.prototype, 'insert', function insert( node, value, location ) {\n\t/* eslint-disable no-underscore-dangle */\n\tvar loc;\n\tvar n;\n\tif ( arguments.length > 2 ) {\n\t\tloc = location;\n\t\tif ( loc !== 'before' && loc !== 'after' ) {\n\t\t\tthrow new Error( format( 'invalid argument. Third argument must be a recognized location. Value: `%s`.', loc ) );\n\t\t}\n\t} else {\n\t\tloc = 'after';\n\t}\n\t// Case: insert after last node (equivalent to `push()`)\n\tif ( loc === 'after' && node === this._last ) {\n\t\treturn this.push( value );\n\t}\n\t// Case: insert before first node (equivalent to `unshift()`)\n\tif ( loc === 'before' && node === this._first ) {\n\t\treturn this.unshift( value );\n\t}\n\t// Unfortunately, we need to check whether we have been provided a node belonging to our list by walking the list. If we don't, we could erroneously increment the list length. This means our runtime goes from the theoretical O(1) to O(N).\n\tn = this._first;\n\twhile ( n !== this._last && n !== node ) {\n\t\tn = n._next;\n\t}\n\t// Check if we iterated through the entire list:\n\tif ( n === this._last && n !== node ) {\n\t\tthrow new Error( 'invalid argument. The list does not contain the provided list node.' );\n\t}\n\t// Create a new list node:\n\tn = new Node( value );\n\n\t// Update pointers...\n\tif ( loc === 'after' ) {\n\t\tnode._next._prev = n;\n\t\tn._next = node._next;\n\n\t\tnode._next = n;\n\t\tn._prev = node;\n\t} else {\n\t\tnode._prev._next = n;\n\t\tn._prev = node._prev;\n\n\t\tnode._prev = n;\n\t\tn._next = node;\n\t}\n\t// Increment the list length:\n\tthis._length += 1;\n\n\treturn this;\n\n\t/* eslint-enable no-underscore-dangle */\n});\n\n/**\n* Returns an iterator for iterating over a list.\n*\n* ## Notes\n*\n* - In order to prevent confusion arising from list mutation during iteration, a returned iterator **always** iterates over a list \"snapshot\", which is defined as the list of elements at the time of this method's invocation.\n*\n* @name iterator\n* @memberof DoublyLinkedList.prototype\n* @type {Function}\n* @param {string} [direction=\"forward\"] - iteration direction\n* @throws {Error} must provide a recognized iteration direction\n* @returns {Iterator} iterator\n*\n* @example\n* var list = new DoublyLinkedList();\n*\n* // Add values to the list:\n* list.push( 'foo' ).push( 'bar' );\n*\n* // Create an iterator:\n* var it = list.iterator();\n*\n* // Iterate over the list...\n* var v = it.next().value;\n* // returns 'foo'\n*\n* v = it.next().value;\n* // returns 'bar'\n*\n* var bool = it.next().done;\n* // returns true\n*/\nsetReadOnly( DoublyLinkedList.prototype, 'iterator', function iterator( direction ) {\n\tvar values;\n\tvar iter;\n\tvar self;\n\tvar FLG;\n\tvar dir;\n\tvar inc;\n\tvar i;\n\tif ( arguments.length ) {\n\t\tdir = direction;\n\t\tif ( dir !== 'forward' && dir !== 'reverse' ) {\n\t\t\tthrow new Error( format( 'invalid argument. Must provide a recognized iteration direction. Value: `%s`.', dir ) );\n\t\t}\n\t} else {\n\t\tdir = 'forward';\n\t}\n\tself = this;\n\n\t// Initialize the iteration index:\n\tif ( dir === 'forward' ) {\n\t\ti = -1;\n\t\tinc = 1;\n\t} else {\n\t\ti = this._length;\n\t\tinc = -1;\n\t}\n\t// Create a copy of list values (necessary in order to \"snapshot\" the list; otherwise, values could come and go between calls to `next`):\n\tvalues = this.toArray();\n\n\t// Create an iterator protocol-compliant object:\n\titer = {};\n\tsetReadOnly( iter, 'next', next );\n\tsetReadOnly( iter, 'return', end );\n\tif ( iteratorSymbol ) {\n\t\tsetReadOnly( iter, iteratorSymbol, factory );\n\t}\n\treturn iter;\n\n\t/**\n\t* Returns an iterator protocol-compliant object containing the next iterated value.\n\t*\n\t* @private\n\t* @returns {Object} iterator protocol-compliant object\n\t*/\n\tfunction next() {\n\t\ti += inc;\n\t\tif ( FLG || i < 0 || i >= values.length ) {\n\t\t\treturn {\n\t\t\t\t'done': true\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\t'value': values[ i ],\n\t\t\t'done': false\n\t\t};\n\t}\n\n\t/**\n\t* Finishes an iterator.\n\t*\n\t* @private\n\t* @param {*} [value] - value to return\n\t* @returns {Object} iterator protocol-compliant object\n\t*/\n\tfunction end( value ) {\n\t\tFLG = true;\n\t\tif ( arguments.length ) {\n\t\t\treturn {\n\t\t\t\t'value': value,\n\t\t\t\t'done': true\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\t'done': true\n\t\t};\n\t}\n\n\t/**\n\t* Returns a new iterator.\n\t*\n\t* @private\n\t* @returns {Iterator} iterator\n\t*/\n\tfunction factory() {\n\t\treturn self.iterator();\n\t}\n});\n\n/**\n* Returns the last node.\n*\n* @name last\n* @memberof DoublyLinkedList.prototype\n* @type {Function}\n* @returns {(Node|void)} list node\n*\n* @example\n* var list = new DoublyLinkedList();\n*\n* // Add values to the list:\n* list.push( 'foo' ).push( 'bar' );\n*\n* // Peek at the last value:\n* var v = list.last().value;\n* // returns 'bar'\n*/\nsetReadOnly( DoublyLinkedList.prototype, 'last', function last() {\n\tif ( this._length ) {\n\t\treturn this._last;\n\t}\n});\n\n/**\n* List length.\n*\n* @name length\n* @memberof DoublyLinkedList.prototype\n* @type {NonNegativeInteger}\n*\n* @example\n* var list = new DoublyLinkedList();\n*\n* // Examine the initial list length:\n* var len = list.length;\n* // returns 0\n*\n* // Add values to the list:\n* list.push( 'foo' ).push( 'bar' );\n*\n* // Retrieve the current list length:\n* len = list.length;\n* // returns 2\n*/\nsetReadOnlyAccessor( DoublyLinkedList.prototype, 'length', function get() {\n\treturn this._length;\n});\n\n/**\n* Removes a value from the end of the list.\n*\n* @name pop\n* @memberof DoublyLinkedList.prototype\n* @type {Function}\n* @returns {(*|void)} removed value\n*\n* @example\n* var list = new DoublyLinkedList();\n*\n* // Add values to the list:\n* list.push( 'foo' ).push( 'bar' );\n*\n* // Remove the last value:\n* var v = list.pop();\n* // returns 'bar'\n*\n* // Add a new value to the list:\n* list.push( 'beep' );\n*\n* // Remove the last value:\n* v = list.pop();\n* // returns 'beep'\n*/\nsetReadOnly( DoublyLinkedList.prototype, 'pop', function pop() {\n\t/* eslint-disable no-underscore-dangle */\n\tvar value;\n\tif ( this._length ) {\n\t\t// Retrieve the last value:\n\t\tvalue = this._last.value;\n\n\t\t// Check whether we have a new \"tail\" or whether we have emptied the list...\n\t\tif ( this._last._prev ) {\n\t\t\tthis._last = this._last._prev;\n\t\t\tthis._last._next = null;\n\t\t} else {\n\t\t\t// List is empty:\n\t\t\tthis._first = null;\n\t\t\tthis._last = null;\n\t\t}\n\t\t// Decrement the list length:\n\t\tthis._length -= 1;\n\t}\n\treturn value;\n\n\t/* eslint-enable no-underscore-dangle */\n});\n\n/**\n* Adds a value to the end of the list.\n*\n* @name push\n* @memberof DoublyLinkedList.prototype\n* @type {Function}\n* @returns {DoublyLinkedList} list instance\n*\n* @example\n* var list = new DoublyLinkedList();\n*\n* // Add values to the list:\n* list.push( 'foo' ).push( 'bar' );\n*\n* // Remove the last value:\n* var v = list.pop();\n* // returns 'bar'\n*\n* // Add a new value to the list:\n* list.push( 'beep' );\n*\n* // Remove the last value:\n* v = list.pop();\n* // returns 'beep'\n*/\nsetReadOnly( DoublyLinkedList.prototype, 'push', function push( value ) {\n\tvar node;\n\n\t// Create a new list node:\n\tnode = new Node( value );\n\n\t// Check whether the list is currently empty...\n\tif ( this._length === 0 ) {\n\t\t// This is the only list node, making it both the first and last node:\n\t\tthis._first = node;\n\t\tthis._last = node;\n\t} else {\n\t\t// Link the new node to the previous last node:\n\t\tnode._prev = this._last; // eslint-disable-line no-underscore-dangle\n\n\t\t// Link the previous last node to the new node:\n\t\tthis._last._next = node; // eslint-disable-line no-underscore-dangle\n\n\t\t// Update the pointer for the last node:\n\t\tthis._last = node;\n\t}\n\t// Increment the list length:\n\tthis._length += 1;\n\n\treturn this;\n});\n\n/**\n* Removes a list node from the list.\n*\n* @name remove\n* @memberof DoublyLinkedList.prototype\n* @type {Function}\n* @param {Node} node - node to remove\n* @throws {Error} must provide a node belonging to the list\n* @returns {(*|void)} removed value\n*\n* @example\n* var list = new DoublyLinkedList();\n*\n* // Add values to the list:\n* list.push( 'foo' ).push( 'bar' ).push( 'beep' );\n*\n* // Determine the list length:\n* var len = list.length;\n* // returns 3\n*\n* // Get the second node:\n* var node = list.first().next;\n*\n* // Remove the second node:\n* var v = list.remove( node );\n* // returns 'bar'\n*\n* // Determine the list length:\n* len = list.length;\n* // returns 2\n*/\nsetReadOnly( DoublyLinkedList.prototype, 'remove', function remove( node ) {\n\t/* eslint-disable no-underscore-dangle */\n\tvar value;\n\tvar n;\n\n\t// Case: first node (equivalent to `shift()`)\n\tif ( node === this._first ) {\n\t\treturn this.shift();\n\t}\n\t// Case: last node (equivalent to `pop()`)\n\tif ( node === this._last ) {\n\t\treturn this.pop();\n\t}\n\t// Retrieve the node value:\n\tvalue = node.value;\n\n\t// Unfortunately, we need to check whether we have been provided a node belonging to our list by walking the list. If we don't, we could erroneously decrement the list length. This means our runtime goes from the theoretical O(1) to O(N).\n\tn = this._first;\n\twhile ( n !== this._last && n !== node ) {\n\t\tn = n._next;\n\t}\n\t// Check if we iterated through the entire list:\n\tif ( n === this._last ) {\n\t\tthrow new Error( 'invalid argument. The list does not contain the provided list node.' );\n\t}\n\t// Update pointers:\n\tnode._prev._next = node._next;\n\tnode._next._prev = node._prev;\n\n\t// Decrement the list length:\n\tthis._length -= 1;\n\n\treturn value;\n\n\t/* eslint-enable no-underscore-dangle */\n});\n\n/**\n* Removes a value from the beginning of the list.\n*\n* @name shift\n* @memberof DoublyLinkedList.prototype\n* @type {Function}\n* @returns {(*|void)} removed value\n*\n* @example\n* var list = new DoublyLinkedList();\n*\n* // Add values to the list:\n* list.push( 'foo' ).push( 'bar' );\n*\n* // Remove the first value:\n* var v = list.shift();\n* // returns 'foo'\n*\n* // Add a new value to the list:\n* list.push( 'beep' );\n*\n* // Remove the first value:\n* v = list.shift();\n* // returns 'bar'\n*/\nsetReadOnly( DoublyLinkedList.prototype, 'shift', function shift() {\n\t/* eslint-disable no-underscore-dangle */\n\tvar value;\n\tif ( this._length ) {\n\t\t// Retrieve the first value:\n\t\tvalue = this._first.value;\n\n\t\t// Check whether we have a new \"head\" or whether we have emptied the list...\n\t\tif ( this._first._next ) {\n\t\t\tthis._first = this._first._next;\n\t\t\tthis._first._prev = null;\n\t\t} else {\n\t\t\t// List is empty:\n\t\t\tthis._first = null;\n\t\t\tthis._last = null;\n\t\t}\n\t\t// Decrement the list length:\n\t\tthis._length -= 1;\n\t}\n\treturn value;\n\n\t/* eslint-enable no-underscore-dangle */\n});\n\n/**\n* Returns an array of list values.\n*\n* @name toArray\n* @memberof DoublyLinkedList.prototype\n* @type {Function}\n* @returns {Array} list values\n*\n* @example\n* var list = new DoublyLinkedList();\n*\n* // Add values to the list:\n* list.push( 'foo' ).push( 'bar' );\n*\n* // Get an array of list values:\n* var vals = list.toArray();\n* // returns [ 'foo', 'bar' ]\n*/\nsetReadOnly( DoublyLinkedList.prototype, 'toArray', function toArray() {\n\tvar node;\n\tvar out;\n\tvar i;\n\n\tout = [];\n\tnode = this._first;\n\tfor ( i = 0; i < this._length; i++ ) {\n\t\tout.push( node.value );\n\t\tnode = node.next;\n\t}\n\treturn out;\n});\n\n/**\n* Serializes a list as JSON.\n*\n* ## Notes\n*\n* - `JSON.stringify()` implicitly calls this method when stringifying a `DoublyLinkedList` instance.\n*\n* @name toJSON\n* @memberof DoublyLinkedList.prototype\n* @type {Function}\n* @returns {Object} serialized list\n*\n* @example\n* var list = new DoublyLinkedList();\n*\n* // Add values to the list:\n* list.push( 'foo' ).push( 'bar' );\n*\n* // Serialize to JSON:\n* var o = list.toJSON();\n* // returns { 'type': 'doubly-linked-list', 'data': [ 'foo', 'bar' ] }\n*/\nsetReadOnly( DoublyLinkedList.prototype, 'toJSON', function toJSON() {\n\tvar out = {};\n\tout.type = 'doubly-linked-list';\n\tout.data = this.toArray();\n\treturn out;\n});\n\n/**\n* Adds a value to the beginning of the list.\n*\n* @name unshift\n* @memberof DoublyLinkedList.prototype\n* @type {Function}\n* @returns {DoublyLinkedList} list instance\n*\n* @example\n* var list = new DoublyLinkedList();\n*\n* // Add values to the beginning of the list:\n* list.unshift( 'foo' ).unshift( 'bar' );\n*\n* // Remove the last value:\n* var v = list.pop();\n* // returns 'foo'\n*\n* // Add a new value to the beginning of the list:\n* list.unshift( 'beep' );\n*\n* // Remove the last value:\n* v = list.pop();\n* // returns 'bar'\n*/\nsetReadOnly( DoublyLinkedList.prototype, 'unshift', function unshift( value ) {\n\tvar node;\n\n\t// Create a new list node:\n\tnode = new Node( value );\n\n\t// Check whether the list is currently empty...\n\tif ( this._length === 0 ) {\n\t\t// This is the only list node, making it both the first and last node:\n\t\tthis._first = node;\n\t\tthis._last = node;\n\t} else {\n\t\t// Link the new node to the previous first node:\n\t\tnode._next = this._first; // eslint-disable-line no-underscore-dangle\n\n\t\t// Link the previous first node to the new node:\n\t\tthis._first._prev = node; // eslint-disable-line no-underscore-dangle\n\n\t\t// Update the pointer for the first node:\n\t\tthis._first = node;\n\t}\n\t// Increment the list length:\n\tthis._length += 1;\n\n\treturn this;\n});\n\n\n// EXPORTS //\n\nmodule.exports = DoublyLinkedList;\n", "/**\n* @license Apache-2.0\n*\n* Copyright (c) 2018 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n/**\n* Doubly linked list.\n*\n* @module @stdlib/dstructs-doubly-linked-list\n*\n* @example\n* var doublyLinkedList = require( '@stdlib/dstructs-doubly-linked-list' );\n*\n* var list = doublyLinkedList();\n*\n* // Add values to the list:\n* list.push( 'foo' ).push( 'bar' );\n*\n* // Remove the last value:\n* var v = list.pop();\n* // returns 'bar'\n*\n* // Add a new value to the list:\n* list.push( 'beep' );\n*\n* // Remove the first list value:\n* v = list.shift();\n* // returns 'foo'\n*/\n\n// MODULES //\n\nvar main = require( './main.js' );\n\n\n// EXPORTS //\n\nmodule.exports = main;\n"],
5
+ "mappings": "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",
6
+ "names": ["require_node", "__commonJSMin", "exports", "module", "defineProperty", "Node", "value", "require_main", "__commonJSMin", "exports", "module", "setReadOnly", "setReadOnlyAccessor", "iteratorSymbol", "format", "Node", "DoublyLinkedList", "node", "value", "location", "loc", "n", "direction", "values", "iter", "self", "FLG", "dir", "inc", "i", "next", "end", "factory", "out", "main"]
7
+ }
@@ -0,0 +1,412 @@
1
+ /*
2
+ * @license Apache-2.0
3
+ *
4
+ * Copyright (c) 2021 The Stdlib Authors.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ // TypeScript Version: 4.1
20
+
21
+ /* eslint-disable max-classes-per-file */
22
+
23
+ /// <reference types="@stdlib/types"/>
24
+
25
+ import { IterableIterator } from '@stdlib/types/iter';
26
+
27
+ /**
28
+ * List node.
29
+ */
30
+ declare class Node {
31
+ /**
32
+ * List node constructor.
33
+ *
34
+ * @param value - node value
35
+ * @returns Node instance
36
+ *
37
+ * @example
38
+ * var node = new Node( 'foo' );
39
+ * // returns <Node>
40
+ */
41
+ constructor( value: any );
42
+
43
+ /**
44
+ * Node value.
45
+ */
46
+ value: any;
47
+
48
+ /**
49
+ * Next node in the list.
50
+ */
51
+ readonly next: Node;
52
+
53
+ /**
54
+ * Previous node in the list.
55
+ */
56
+ readonly prev: Node;
57
+
58
+ /**
59
+ * Private field pointing to the next node.
60
+ */
61
+ private readonly _next: Node;
62
+
63
+ /**
64
+ * Private field pointing to the previous node.
65
+ */
66
+ private readonly _prev: Node;
67
+ }
68
+
69
+ /**
70
+ * Doubly linked list.
71
+ */
72
+ declare class DoublyLinkedList {
73
+ /**
74
+ * Doubly linked list constructor.
75
+ *
76
+ * @returns linked list instance
77
+ *
78
+ * @example
79
+ * var list = new DoublyLinkedList();
80
+ *
81
+ * // Add values to the list:
82
+ * list.push( 'foo' ).push( 'bar' );
83
+ *
84
+ * // Remove the last value:
85
+ * var v = list.pop();
86
+ * // returns 'bar'
87
+ *
88
+ * // Add a new value to the list:
89
+ * list.push( 'beep' );
90
+ *
91
+ * // Remove the first value:
92
+ * v = list.shift();
93
+ * // returns 'foo'
94
+ */
95
+ constructor();
96
+
97
+ /**
98
+ * Clears the list.
99
+ *
100
+ * @returns list instance
101
+ *
102
+ * @example
103
+ * var list = new DoublyLinkedList();
104
+ *
105
+ * // Add values to the list:
106
+ * list.push( 'foo' ).push( 'bar' );
107
+ *
108
+ * // Peek at the first value:
109
+ * var v = list.first().value;
110
+ * // returns 'foo'
111
+ *
112
+ * // Examine the list length:
113
+ * var len = list.length;
114
+ * // returns 2
115
+ *
116
+ * // Clear all list items:
117
+ * list.clear();
118
+ *
119
+ * // Peek at the first value:
120
+ * v = list.first();
121
+ * // returns undefined
122
+ *
123
+ * // Examine the list length:
124
+ * len = list.length;
125
+ * // returns 0
126
+ */
127
+ clear(): DoublyLinkedList;
128
+
129
+ /**
130
+ * Returns the first list node.
131
+ *
132
+ * @returns list node
133
+ *
134
+ * @example
135
+ * var list = new DoublyLinkedList();
136
+ *
137
+ * // Add values to the list:
138
+ * list.push( 'foo' ).push( 'bar' );
139
+ *
140
+ * // Peek at the first value:
141
+ * var v = list.first().value;
142
+ * // returns 'foo'
143
+ */
144
+ first(): Node | void;
145
+
146
+ /**
147
+ * Inserts a value into the list either before or after a provided list node.
148
+ *
149
+ * @param node - node after which to insert the value
150
+ * @param value - value to insert
151
+ * @param location - location (default: 'after')
152
+ * @throws must provide a node belonging to the list
153
+ * @throws must provide a recognized location
154
+ * @returns list instance
155
+ *
156
+ * @example
157
+ * var list = new DoublyLinkedList();
158
+ *
159
+ * // Add values to the list:
160
+ * list.push( 'foo' ).push( 'bar' ).push( 'beep' );
161
+ *
162
+ * // Determine the list length:
163
+ * var len = list.length;
164
+ * // returns 3
165
+ *
166
+ * // Get the second node:
167
+ * var node = list.first().next;
168
+ *
169
+ * // Insert a value after the second node:
170
+ * list.insert( node, 'boop' );
171
+ *
172
+ * // Determine the list length:
173
+ * len = list.length;
174
+ * // returns 4
175
+ */
176
+ insert( node: Node, value: unknown, location?: 'before' | 'after' ): DoublyLinkedList;
177
+
178
+ /**
179
+ * Returns an iterator for iterating over a list.
180
+ *
181
+ * ## Notes
182
+ *
183
+ * - In order to prevent confusion arising from list mutation during iteration, a returned iterator **always** iterates over a list "snapshot", which is defined as the list of elements at the time of this method's invocation.
184
+ *
185
+ * @param direction - iteration direction (default: 'forward')
186
+ * @throws must provide a recognized iteration direction
187
+ * @returns iterator
188
+ *
189
+ * @example
190
+ * var list = new DoublyLinkedList();
191
+ *
192
+ * // Add values to the list:
193
+ * list.push( 'foo' ).push( 'bar' );
194
+ *
195
+ * // Create an iterator:
196
+ * var it = list.iterator();
197
+ *
198
+ * // Iterate over the list...
199
+ * var v = it.next().value;
200
+ * // returns 'foo'
201
+ *
202
+ * v = it.next().value;
203
+ * // returns 'bar'
204
+ *
205
+ * var bool = it.next().done;
206
+ * // returns true
207
+ */
208
+ iterator( direction?: 'forward' | 'reverse' ): IterableIterator;
209
+
210
+ /**
211
+ * Returns the last node.
212
+ *
213
+ * @returns list node
214
+ *
215
+ * @example
216
+ * var list = new DoublyLinkedList();
217
+ *
218
+ * // Add values to the list:
219
+ * list.push( 'foo' ).push( 'bar' );
220
+ *
221
+ * // Peek at the last value:
222
+ * var v = list.last().value;
223
+ * // returns 'bar'
224
+ */
225
+ last(): Node | void;
226
+
227
+ /**
228
+ * List length.
229
+ *
230
+ * @example
231
+ * var list = new DoublyLinkedList();
232
+ *
233
+ * // Examine the initial list length:
234
+ * var len = list.length;
235
+ * // returns 0
236
+ *
237
+ * // Add values to the list:
238
+ * list.push( 'foo' ).push( 'bar' );
239
+ *
240
+ * // Retrieve the current list length:
241
+ * len = list.length;
242
+ * // returns 2
243
+ */
244
+ readonly length: number;
245
+
246
+ /**
247
+ * Removes a value from the end of the list.
248
+ *
249
+ * @example
250
+ * var list = new DoublyLinkedList();
251
+ *
252
+ * // Add values to the list:
253
+ * list.push( 'foo' ).push( 'bar' );
254
+ *
255
+ * // Remove the last value:
256
+ * var v = list.pop();
257
+ * // returns 'bar'
258
+ *
259
+ * // Add a new value to the list:
260
+ * list.push( 'beep' );
261
+ *
262
+ * // Remove the last value:
263
+ * v = list.pop();
264
+ * // returns 'beep'
265
+ */
266
+ pop(): any;
267
+
268
+ /**
269
+ * Adds a value to the end of the list.
270
+ *
271
+ * @returns list instance
272
+ *
273
+ * @example
274
+ * var list = new DoublyLinkedList();
275
+ *
276
+ * // Add values to the list:
277
+ * list.push( 'foo' ).push( 'bar' );
278
+ *
279
+ * // Remove the last value:
280
+ * var v = list.pop();
281
+ * // returns 'bar'
282
+ *
283
+ * // Add a new value to the list:
284
+ * list.push( 'beep' );
285
+ *
286
+ * // Remove the last value:
287
+ * v = list.pop();
288
+ * // returns 'beep'
289
+ */
290
+ push(): DoublyLinkedList;
291
+
292
+ /**
293
+ * Removes a list node from the list.
294
+ *
295
+ * @param node - node to remove
296
+ * @throws must provide a node belonging to the list
297
+ * @returns removed value
298
+ *
299
+ * @example
300
+ * var list = new DoublyLinkedList();
301
+ *
302
+ * // Add values to the list:
303
+ * list.push( 'foo' ).push( 'bar' ).push( 'beep' );
304
+ *
305
+ * // Determine the list length:
306
+ * var len = list.length;
307
+ * // returns 3
308
+ *
309
+ * // Get the second node:
310
+ * var node = list.first().next;
311
+ *
312
+ * // Remove the second node:
313
+ * var v = list.remove( node );
314
+ * // returns 'bar'
315
+ *
316
+ * // Determine the list length:
317
+ * len = list.length;
318
+ * // returns 2
319
+ */
320
+ remove( node: Node ): any;
321
+
322
+ /**
323
+ * Removes a value from the beginning of the list.
324
+ *
325
+ * @returns removed value
326
+ *
327
+ * @example
328
+ * var list = new DoublyLinkedList();
329
+ *
330
+ * // Add values to the list:
331
+ * list.push( 'foo' ).push( 'bar' );
332
+ *
333
+ * // Remove the first value:
334
+ * var v = list.shift();
335
+ * // returns 'foo'
336
+ *
337
+ * // Add a new value to the list:
338
+ * list.push( 'beep' );
339
+ *
340
+ * // Remove the first value:
341
+ * v = list.shift();
342
+ * // returns 'bar'
343
+ */
344
+ shift(): any;
345
+
346
+ /**
347
+ * Returns an array of list values.
348
+ *
349
+ * @returns list values
350
+ *
351
+ * @example
352
+ * var list = new DoublyLinkedList();
353
+ *
354
+ * // Add values to the list:
355
+ * list.push( 'foo' ).push( 'bar' );
356
+ *
357
+ * // Get an array of list values:
358
+ * var vals = list.toArray();
359
+ * // returns [ 'foo', 'bar' ]
360
+ */
361
+ toArray(): Array<any>;
362
+
363
+ /**
364
+ * Serializes a list as JSON.
365
+ *
366
+ * ## Notes
367
+ *
368
+ * - `JSON.stringify()` implicitly calls this method when stringifying a `DoublyLinkedList` instance.
369
+ *
370
+ * @returns serialized list
371
+ *
372
+ * @example
373
+ * var list = new DoublyLinkedList();
374
+ *
375
+ * // Add values to the list:
376
+ * list.push( 'foo' ).push( 'bar' );
377
+ *
378
+ * // Serialize to JSON:
379
+ * var o = list.toJSON();
380
+ * // returns { 'type': 'doubly-linked-list', 'data': [ 'foo', 'bar' ] }
381
+ */
382
+ toJSON(): any;
383
+
384
+ /**
385
+ * Adds a value to the beginning of the list.
386
+ *
387
+ * @returns list instance
388
+ *
389
+ * @example
390
+ * var list = new DoublyLinkedList();
391
+ *
392
+ * // Add values to the beginning of the list:
393
+ * list.unshift( 'foo' ).unshift( 'bar' );
394
+ *
395
+ * // Remove the last value:
396
+ * var v = list.pop();
397
+ * // returns 'foo'
398
+ *
399
+ * // Add a new value to the beginning of the list:
400
+ * list.unshift( 'beep' );
401
+ *
402
+ * // Remove the last value:
403
+ * v = list.pop();
404
+ * // returns 'bar'
405
+ */
406
+ unshift(): DoublyLinkedList;
407
+ }
408
+
409
+
410
+ // EXPORTS //
411
+
412
+ export = DoublyLinkedList;
package/lib/index.js ADDED
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @license Apache-2.0
3
+ *
4
+ * Copyright (c) 2018 The Stdlib Authors.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ 'use strict';
20
+
21
+ /**
22
+ * Doubly linked list.
23
+ *
24
+ * @module @stdlib/dstructs-doubly-linked-list
25
+ *
26
+ * @example
27
+ * var doublyLinkedList = require( '@stdlib/dstructs-doubly-linked-list' );
28
+ *
29
+ * var list = doublyLinkedList();
30
+ *
31
+ * // Add values to the list:
32
+ * list.push( 'foo' ).push( 'bar' );
33
+ *
34
+ * // Remove the last value:
35
+ * var v = list.pop();
36
+ * // returns 'bar'
37
+ *
38
+ * // Add a new value to the list:
39
+ * list.push( 'beep' );
40
+ *
41
+ * // Remove the first list value:
42
+ * v = list.shift();
43
+ * // returns 'foo'
44
+ */
45
+
46
+ // MODULES //
47
+
48
+ var main = require( './main.js' );
49
+
50
+
51
+ // EXPORTS //
52
+
53
+ module.exports = main;