2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-16 13:22:11 +00:00
Files
build/new/container.jam
Rene Rivera b864434ac9 Change container/list to container/vector.
Added documentation for container/vector.


[SVN r14293]
2002-07-03 17:18:57 +00:00

237 lines
6.2 KiB
Plaintext

# Copyright (C) 2002, Rene Rivera. Permission to copy, use, modify, sell and
# distribute this software is granted provided this copyright notice appears in
# all copies. This software is provided "as is" without express or implied
# warranty, and with no claim as to its suitability for any purpose.
# Various container classes.
import class : * ;
import sequence ;
# Base for container objects. This lets us construct recursive structures.
# That is containers with containers in them, specifically so we can tell
# literal values from node values.
#
rule node (
value ? # Optional value to set node to initially.
)
{
self.value = $(value) ;
# Set the value of this node, passing nothing will clear it.
#
rule set ( value ? )
{
self.value = $(value) ;
}
# Get the value of this node.
#
rule get ( )
{
return $(self.value) ;
}
}
class node ;
# A simple vector. Interface mimics the C++ std::vector and std::list,
# with the exception that indices are one (1) based to follow Jam standard.
#
# TODO: Possibly add assertion checks.
#
rule vector (
values * # Initial contents of vector.
)
{
node.__init__ ;
self.value = $(values) ;
# Get the value of the first element.
#
rule front ( )
{
return $(self.value[1]) ;
}
# Get the value of the last element.
#
rule back ( )
{
return $(self.value[-1]) ;
}
# Get the value of the element at the given index, one based.
# Access to elements of recursive structures is supported directly.
# Specifying additional index values recursively accesses the elements as
# containers. For example: [ $(v).at 1 : 2 ] would retrieve the second element
# of our first element. This assuming the first element is a container.
#
rule at (
index # The element index, one based.
: * # Additional indices to access recursively.
)
{
local r = $(self.value[$(index)]) ;
if $(2)
{
r = [ $(r).at $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
}
return $(r) ;
}
# Get the value contained in the given element. This has the same
# functionality and interface as "at" but in addition gets the value
# of the referenced element, assuming it's a "node".
#
rule get-at (
index # The element index, one based.
: * # Additional indices to access recursively.
)
{
local r = $(self.value[$(index)]) ;
if $(2)
{
r = [ $(r).at $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
}
return [ $(r).get ] ;
}
# Insert the given value into the front of the vector pushing the
# rest of the elements back.
#
rule push-front (
value # Value to become first element.
)
{
self.value = $(value) $(self.value) ;
}
# Remove the front element from the vector. Does not return the value.
# No effect if vector is empty.
#
rule pop-front ( )
{
self.value = $(self.value[2-]) ;
}
# Add the given value at the end of the vector.
#
rule push-back (
value # Value to become back element.
)
{
self.value += $(value) ;
}
# Remove the back element from the vector. Does not return the value.
# No effect if vector is empty.
#
rule pop-back ( )
{
self.value = $(self.value[1--2]) ;
}
# Insert the given value at the given index, one based. The values
# at and to the right of the of the index are push back to make room
# for the new value.
#
rule insert (
index # The index to insert at, one based.
: value # The value to insert.
)
{
local left = $(self.value[1-$(index)]) ;
left = $(left[1--2]) ;
local right = $(self.value[$(index)-]) ;
self.value = $(left) $(value) $(right) ;
}
# Remove one or more elements from the vector. The range is inclusive,
# and not specifying an end is equivalent to the [start,start] range.
#
rule erase (
start # Index of first element ro remove.
end ? # Optional, index of last element to remove.
)
{
end ?= $(start) ;
local left = $(self.value[1-$(start)]) ;
left = $(left[1--2]) ;
local right = $(self.value[$(end)-]) ;
right = $(right[2-]) ;
self.value = $(left) $(right) ;
}
# Remove all elements from the vector.
#
rule clear ( )
{
self.value = ;
}
# The number of elements in the vector.
#
rule size ( )
{
return [ sequence.length $(self.value) ] ;
}
# Returns "true" if there are NO elements in the vector, empty
# otherwise.
#
rule empty ( )
{
if ! $(self.value)
{
return true ;
}
}
}
class vector : node ;
local rule __test__ ( )
{
import assert ;
local l = [ new vector ] ;
assert.result 0 : $(l).size ;
$(l).push-back b ;
$(l).push-front a ;
assert.result a : $(l).front ;
assert.result b : $(l).back ;
$(l).insert 2 : d ;
$(l).insert 2 : c ;
$(l).insert 4 : f ;
$(l).insert 4 : e ;
$(l).pop-back ;
assert.result 5 : $(l).size ;
assert.result d : $(l).at 3 ;
$(l).pop-front ;
assert.result c : $(l).front ;
assert.false $(l).empty ;
$(l).erase 3 4 ;
assert.result 2 : $(l).size ;
local l2 = [ new vector q w e r t y ] ;
assert.result 6 : $(l2).size ;
$(l).push-back $(l2) ;
assert.result 3 : $(l).size ;
local l2-alias = [ $(l).back ] ;
assert.result e : $(l2-alias).at 3 ;
$(l).clear ;
assert.true $(l).empty ;
assert.false $(l2-alias).empty ;
$(l2).pop-back ;
assert.result t : $(l2-alias).back ;
local l3 = [ new vector ] ;
$(l3).push-back [ new vector 1 2 3 4 5 ] ;
$(l3).push-back [ new vector a b c ] ;
$(l3).push-back [ new vector [ new vector x y z ] [ new vector 7 8 9 ] ] ;
assert.result 1 : $(l3).at 1 : 1 ;
assert.result b : $(l3).at 2 : 2 ;
assert.result a b c : $(l3).get-at 2 ;
assert.result 7 8 9 : $(l3).get-at 3 : 2 ;
}