gauche.uvector
- Uniform vector library ¶Provides procedures that work on uniform vectors
(see Uniform vectors).
This module is a superset of R7RS uniform vector library
(scheme.vector.@
) and SRFI-4.
The @
part is actually one of u8
, s8
, u16
,
s16
, u32
, s32
, u64
, s64
,
f16
, f32
, f64
, c32
, c64
or c128
.
Gauche’s extension to SRFI-160 is as follows:
f16vector
and c32vector
, using 16-bit floating
point numbers as used in high-dynamic range image format.
@vector-add
.
gauche.collection
- Collection framework)
and the sequence framework (see gauche.sequence
- Sequence framework). So the
methods like map
, for-each
, ref
or subseq
can be used.
@vector-ref
takes optional fallback value.
When you try to store a number out of the range of the vector type, an error is signaled by default. However, some procedures take an optional argument clamp that specifies alternative behavior in such a case. Clamp argument may take one of the following values.
#f
Default behavior (signals an error).
high
Clamps high bound; i.e. if the value to be stored is beyond the higher bound of the range, the maximum value is stored instead.
low
Clamps low bound; i.e. if the value to be stored is below the lower bound of the range, the minimum value is stored instead.
both
Clamps both sides; does both high
and low
.
(list->u8vector '(-1)) ⇒ error (list->u8vector '(-1) 'low) ⇒ #u8(0) (list->u8vector '(-1) 'high) ⇒ error (list->u8vector '(3000) 'high) ⇒ #u8(255) (list->u8vector '(-100 20 300) 'both) ⇒ #u8(0 20 255)
In the following description, @
can be replaced
for any of s8
, u8
, s16
, u16
,
s32
, u32
, s64
, u64
,
f16
, f32
, f64
, c32
, c64
or c128
.
Note: R7RS-large provides separate library for each type,
and you should import them individually, for example,
(use scheme.vector.u8)
(Gauche way) or
(import (scheme vector u8))
(R7RS way).
On the other hand, using gauche.uvector
imports all the bindings.
• Uvector basic operations: | ||
• Uvector conversion operations: | ||
• Uvector numeric operations: | ||
• Uvector block I/O: | ||
• Bytevector compatibility: |
The following procedures are built-in; see Uniform vectors:
make-@vector uvector? @vector? uvector-ref @vector-ref uvector-set! @vector-set! uvector-length
[R7RS vector.@]
{gauche.uvector
}
Returns #t
iff obj can be an element of @vector
.
[R7RS vector.@]
{gauche.uvector
}
The argument must be a @vector.
Returns #t
iff it is empty.
[R7RS vector.@]
{gauche.uvector
}
Constructs @vector whose elements are numbers x ….
The numbers must be exact integer for exact integer vectors,
and in the valid range of the vector.
(s8vector 1 2 3) ⇒ #s8(1 2 3)
class
len
:optional fill
¶{gauche.uvector
}
This is a Gauche extension; instead of using separate constructor for
each uvector type, you can pass the class of desired uvector.
Type-specific constructors (make-s8vector
etc.) are defined
in the core library (see Uniform vectors).
(make-uvector <u8vector> 3) ⇒ #u8(0 0 0) (make-uvector <s8vector> 5 -1) ⇒ #s8(-1 -1 -1 -1 -1)
[R7RS vector.@]
{gauche.uvector
}
Construct a @vector of length len, with each element
as a result of (f seed)
, (f (f seed))
,
(f (f (f seed)))
, ….
@vector-unfold fills the element from left to right,
while @vector-unfold-right from right to left.
(u8vector-unfold (cut + 2 <>) 5 0) ⇒ #u8(2 4 6 8 10) (u8vector-unfold-right (pa$ + 2) 5 0) ⇒ #u8(10 8 6 4 2)
[R7RS vector.@]
{gauche.uvector
}
Fill an @vector vec between start-th index (inclusive)
and end-th index (exclusive), with the values generated by f,
which is called with two arguments, the integer index and
the current seed value.
In @vector-unfold!
, f is first called with
start and seed. It must return two values,
the element to put to vec and the next seed value.
Then f is called with start + 1 and the previously
returnd seed value, and so on, until end - start elements
are generated.
@vector-unfold-right!
works similarly, but the elements
are generated from right (end-1) to left (start).
If start >= end, f is never called and vec isn’t altered. It is an error if the index falls out of range of vec.
Return an unspecified vlaue.
[R7RS vector.@]
{gauche.uvector
}
Returns the length of the @vector vec.
Note that the generic function size-of
can be used
to obtain the length of vec as well,
if you import gauche.collection
(see gauche.collection
- Collection framework).
(s16vector-length '#s16(111 222 333)) ⇒ 3 (use gauche.collection) (size-of '#s16(111 222 333)) ⇒ 3
{gauche.uvector
}
This function can be applied to any type of uniform vectors, and
returns the raw size of the uvector in number of octets.
When start and/or end is/are given, the size of data
between those indices are calculated. The special value -1
for end indicates the end of the vector.
The returned value matches the number of octets to be written out
by (write-uvector uvector port start end)
.
(Do not confuse this with uvector-length
, which returns
the number of elements.)
(uvector-size '#u8(1 2 3)) ⇒ 3 (uvector-size '#u64(1 2 3)) ⇒ 24 (uvector-size '#u32(0 1 2 3) 2) ⇒ 8 (uvector-size '#u32(0 1 2 3) 0 1) ⇒ 4
{gauche.uvector
}
Returns the size of an element of a uvector of the given class, in bytes.
An error is raised when class is not a uvector class.
(uvector-class-element-size <u8vector>) ⇒ 1 (uvector-class-element-size <s64vector>) ⇒ 8
[R7RS vector.@]
{gauche.uvector
}
Interchanges ith and jth elements of the uvector vec.
Return value is not specified.
{gauche.uvector
}
Stores fill in every element of vec,
ranging from start to end of vec,
if they are given.
Return value is not specified.
[R7RS vector.@]
{gauche.uvector
}
All arguments must be @vectors. Returns #t
iff
all arguments have the same length and has the same values (in terms of =
)
at the corresponding position. Zero arguments
return #t.
Note that in Gauche you can compare uvectors with equal?
as well.
[SRFI-66]{gauche.uvector
}
Note: This is provided only for the SRFI-66 compatibility.
Use @vector=
instead.
Both arguments must be a @vector. Returns #t
if
vec1 and vec2 are equal to each other, #f
otherwise.
[SRFI-66]{gauche.uvector
}
Both arguments must be a @vector. Returns -1
if
vec1 is smaller than vec2,
0
if both are equal to each other,
and 1
if vec1 is greater than vec2.
Shorter vector is smaller than longer vectors. If the lengths of both vectors are the same, elements are compared from left to right.
Note that you can compare uvectors with compare
in Gauche.
These are provided because SRFI-66 defines u8vector-compare
.
You can also use them to indicate arguments are vectors of the specific type.
[R7RS vector.@]
{gauche.uvector
}
Returns a fresh copy of uniform vector vec.
If start and/or end are given, they limit the range of
vec to be copied.
(u8vector-copy '#u8(1 2 3 4)) ⇒ #u8(1 2 3 4) (u8vector-copy '#u8(1 2 3 4) 2) ⇒ #u8(3 4) (u8vector-copy '#u8(1 2 3 4) 1 3) ⇒ #u8(2 3)
{gauche.uvector
}
This is a generic version of @vector-copy
.
You can give any type of uvector to vec, and get its copy
(or copy of its part, depending on start/end argument).
[R7RS vector.@]
{gauche.uvector
}
Copies vec between strat and end index, but
reversing it.
(u8vector-reverse-copy '#u8(1 2 3 4 5)) ⇒ #u8(5 4 3 2 1) (u8vector-reverse-copy '#u8(1 2 3 4 5) 1 4) ⇒ #u8(4 3 2)
[R7RS vector.@]
{gauche.uvector
}
Both target and source must be @vectors, and
target must be mutable.
This procedure copies the elements of source, beginning from index
sstart (inclusive) and up to send, into target,
beginning from index tstart. sstart and send
may be omitted, and in that case 0 and the length of source
are assumed, respectively.
(let ((target (u8vector 0 1 2 3 4 5 6))) (u8vector-copy! target 2 '#u8(10 11 12 13 14) 1 4) target) ⇒ #u8(0 1 11 12 13 6)
If the number of elements in the source vector between sstart and send is larger than the target vector beginning from tstart, the excess elements are silently discarded.
It is ok to pass the same vector to target and source; it always works even if the regions of source and destination are overlapping.
Note: This procedure used to take just two uniform vectors, target and source, and just copies contents of source to target. Both vectors had to be the same type and same length. The API is revised according to SRFI-160. The old interface is still supported for the backward compatibility, but it is deprecated and will be gone in the future releases.
Also note that SRFI-66 provides uvector-copy!
with different
argument order (see srfi.66
- Octet vectors).
[R7RS vector.@]
{gauche.uvector
}
[R7RS vector.@]
{gauche.uvector
}
{gauche.uvector
}
This procedure allows different parts of the source uvector source into
various parts of the target uvector target, all at once.
When ssize is omitted or zero, this procedure does the following:
;; For each i from 0 to count: (u8vector-copy! target (+ tstart (* i tstride)) source sstart)
That is, it copies the content of source (offset by sstart, which defaults to 0) into the target repeatedly, advancing index with tstride. If either the target index reaches the end or count copies are made, the procedure returns. See the example:
(define t (make-u8vector 10 0)) (u8vector-multi-copy! t 0 4 '#u8(1 2 3)) t ⇒ #u8(1 2 3 0 1 2 3 0 1 2)
If ssize is given and positive, the source is also splitted as follows:
;; For each i from 0 to count: (u8vector-copy! target (+ tstart (* i tstride)) source (+ sstart (* i sstride)) (+ sstart (* i sstride) ssize))
That is, each ssize slice from source, is copied into target, advancing source index by sstride and the destination index by dstride. In this case, sstride defaults to ssize if omitted.
(define t (make-u8vector 12 0)) (u8vector-multi-copy! t 0 4 '#u8(1 2 3 4 5 6 7 8 9) 0 3) t ⇒ #u8(1 2 3 0 4 5 6 0 7 8 9 0)
The operation ends when either count slices are copied, or destination index or source index reaches the end.
Hint: If you want to copy a part of the source vector repeatedly (instead of to its end), you can specify 0 to sstride:
(define t (make-u8vector 12 0)) (u8vector-multi-copy! t 0 4 '#u8(1 2 3 4 5 6 7 8 9) 2 4 0) t ⇒ #u8(3 4 5 6 3 4 5 6 3 4 5 6)
Using collection and sequence framework, you can perform various operations on the homogeneous vectors.
(use gauche.collection) (use gauche.sequence) (fold + 0 '#s32(1 2 3 4)) ⇒ 10 (map-to <f32vector> * '#f32(3.2 1.1 4.3) '#f32(-4.3 2.2 9.4)) ⇒ #f32(-13.760001 2.420000 40.420002) (subseq #u32(1 4 3 4 5) 2 4) ⇒ #u32(3 4)
{gauche.uvector
}
This is a generic version of @vector-copy!
.
The destination target and the source source can be
any type of uniform vectors, and they don’t need to match.
The copy is done bit-by-bit. So if you copy to a different type
of uvector, the result depends on how the numbers are represented
internally. This is mainly to manipulate binary data.
Tstart is interpreted according to the type of target, and sstart and send are interpreted according to the type of source.
(rlet1 v (make-u8vector 6 0) (uvector-copy! v 1 '#u32(0 #x01020304 0) 1 2)) ⇒ #u8(0 1 2 3 4 0) or #u8(0 4 3 2 1 0)
[R7RS vector.@]
{gauche.uvector
}
All arguments must be @vectors. Returns a fresh vector
whose contents are concatenation of the given vectors.
(It returns a fresh vector even there’s only one argument).
(u8vector-append '#u8(1 2 3) '#u8(4 5) '#u8() '#u8(6 7 8)) ⇒ #u8(1 2 3 4 5 6 7 8)
[R7RS vector.@]
{gauche.uvector
}
Returns a new @vector which is concatenation of the list of
@vectors vecs.
(u8vector-concatenate '(#u8(1 2 3) #u8(4 5 6))) ⇒ #u8(1 2 3 4 5 6)
[R7RS vector.@]
{gauche.uvector
}
Returns a new @vector which is concatenation of the subvectors of
given vecs, using accompanied start and end index.
(u8vector-append-subvectors '#u8(1 2 3 4) 1 3 '#u8(5 6 7 8) 0 2) ⇒ #u8(2 3 5 6)
[R7RS vector.@]
{gauche.uvector
}
Returns a new uvector that has the first n elements,
the last n elements, the elements without the first n elements,
and the elements without the last n elements, respectively.
N must be a nonnegative exact integer no greater than the length of vec.
(u8vector-take '#u8(0 1 2 3 4 5) 4) ⇒ #u8(0 1 2 3) (u8vector-drop '#u8(0 1 2 3 4 5) 4) ⇒ #u8(4 5) (u8vector-take-right '#u8(0 1 2 3 4 5) 4) ⇒ #u8(2 3 4 5) (u8vector-drop-right '#u8(0 1 2 3 4 5) 4) ⇒ #u8(0 1)
You can also use uvector-alias
to obtain a partial uvector
that shares the storage with the original uvector, avoiding copying overhead.
[R7RS vector.@]
{gauche.uvector
}
Segment vec into fresh uvectors of length n, and returns
a list of them. The last uvector may be shorter than n if the
length of vec is not a multiple of n.
N must be a positive exact integer.
(u8vector-segment '#u8(0 1 2 3 4 5 6 7) 3) ⇒ (#u8(0 1 2) #u8(3 4 5) #u8(6 7))
[R7RS vector.@]
{gauche.uvector
}
[R7RS vector.@]
{gauche.uvector
}
[R7RS vector.@]
{gauche.uvector
}
[R7RS vector.@]
{gauche.uvector
}
[R7RS vector.@]
{gauche.uvector
}
[R7RS vector.@]
{gauche.uvector
}
[R7RS vector.@]
{gauche.uvector
}
[R7RS vector.@]
{gauche.uvector
}
[R7RS vector.@]
{gauche.uvector
}
[R7RS vector.@]
{gauche.uvector
}
[R7RS vector.@]
{gauche.uvector
}
[R7RS vector.@]
{gauche.uvector
}
[R7RS vector.@]
{gauche.uvector
}
Bound to comparators that can compare two @vector
s and
to hash a @vector
. See Basic comparators, for the details
of comparators. These comparators both provides ordering predicate
and hash function.
{gauche.uvector
}
The uvector
must contain values in increasing order.
This procedure finds the index of an element that is equal to key,
using binary search. If such element can’t be found, #f
is returned.
(uvector-binary-search '#u8(0 5 19 32 58 96) 32) ⇒ 3 (uvector-binary-search '#u8(0 5 19 32 58 96) 33) ⇒ #f
The optional start and end arguments limits the portion
of uvector to search; start specifies starting index (inclusive)
and end specifies ending index (exclusive).
Passing #f
indicates the default
value (0 for start, the length of the vector for end).
The returned index is the actual index of the vector, but the elements
outside of start-end range don’t need to be sorted.
(uvector-binary-search '#u8(99 99 19 32 58 99) 32 2 5) ⇒ 3 (uvector-binary-search '#u8(99 99 19 32 58 99) 99 2 5) ⇒ #f
The optional skip argument must be a nonnegative exact integer
or #f
. If it is a positive integer, the number of elements after
every key in the uvector is ignored. For example, if skip is 2
and uvector is #u8(3 100 101 5 102 103 13 104 105)
,
only 3
, 5
and 13
are subject to search, and elements
inbetween are ignored. This allows the caller to store payload,
or associated value to each key, in the uvector itself.
If skip is positive integer, the length of the searched portion
of uvector must be a multiple of the record size (skip+1).
(uvector-binary-search '#u8(3 100 101 5 102 103 13 104 105) 13 #f #f 2)
⇒ 6
(uvector-binary-search '#u8(3 100 101 5 102 103 13 104) 13 #f #f 2)
⇒ ; Error: uvector size (8) isn’t multiple of record size (3)
Finally, rounding argument adjusts the behavior when the exact match isn’t found. It can be either one of the following values:
#f
This is the default.
The procedure searches the element that is equal to key, and
returns #f
if such element isn’t found.
floor
When the exact match isn’t found, the procedure
returns an index of the element that’s closest to but
not greater than key. If key is smaller than all the elements,
#f
is returned.
ceiling
When the exact match isn’t found, the procedure
returns an index of the element that’s closest to but
not smaller than key. If key is greater than all the elements,
#f
is returned.
(uvector-binary-search '#u32(1 10 100 1000 10000) 3757) ⇒ #f (uvector-binary-search '#u32(1 10 100 1000 10000) 3757 #f #f #f 'floor) ⇒ 3 (uvector-binary-search '#u32(1 10 100 1000 10000) 3757 #f #f #f 'ceiling) ⇒ 4
Note: SRFI-133 has vector-binary-search
, which is quite similar to
this procedure (see scheme.vector
- R7RS vectors) but it requires comparison
procedure, for it needs to compare general Scheme values. And it
does not support skip and rounding arguments.
[R7RS vector.@]
{gauche.uvector
}
Converts @vector vec to a list.
If start and/or end are given, they limit the range of
vec to be extracted.
Note that the generic function coerce-to
can be used as well,
if you import gauche.collection
.
(u32vector->list '#u32(9 2 5)) ⇒ (9 2 5) (use gauche.collection) (coerce-to <list> '#u32(9 2 5)) ⇒ (9 2 5)
{gauche.uvector
}
This is a generic version of @vector->list
.
It can take any kind of uvector as uvec. The meaning of
optional arguments are the same as @vector->list
.
[R7RS vector.@]
{gauche.uvector
}
Converts @vector vec to a vector.
If start and/or end are given, they limit the range of
vec to be copied.
Note that the generic function coerce-to
can be used as well,
if you import gauche.collection
.
(f32vector->vector '#f32(9.3 2.2 5.5)) ⇒ #(9.3 2.2 5.5) (f32vector->vector '#f32(9.3 2.2 5.5) 2) ⇒ #(5.5) (use gauche.collection) (coerce-to <vector> '#f32(9.3 2.2 5.5)) ⇒ #(9.3 2.2 5.5)
{gauche.uvector
}
This is a generic version of @vector->vector
.
It can take any kind of uvector as uvec. The meaning of
optional arguments are the same as @vector->vector
.
[R7RS vector.@]
{gauche.uvector
}
Converts a list list to a @vector.
Optional argument clamp specifies the behavior when
the element of list is out of the valid range.
(The clamp argument is Gauche’s extension.)
Note that the generic function coerce-to
can be used as well,
if you import gauche.collection
.
(list->s64vector '(9 2 5)) ⇒ #s64(9 2 5) (use gauche.collection) (coerce-to <s64vector> '(9 2 5)) ⇒ #s64(9 2 5)
[R7RS vector.@]
{gauche.uvector
}
Create a new @vector
with the elements of list in
reverse order.
Optional argument clamp specifies the behavior when
the element of list is out of the valid range.
(The clamp argument is Gauche’s extension.)
[R7RS vector.@]
{gauche.uvector
}
Converts a vector vec to a @vector.
If start and/or end are given, they limit the range of
vec to be copied.
Optional argument clamp specifies the behavior when
the element of vec is out of the valid range.
(The clamp argument is Gauche’s extension.)
Note that the generic function coerce-to
can be used as well,
if you import gauche.collection
.
(vector->f64vector '#(3.1 5.4 3.2)) ⇒ #f64(3.1 5.4 3.2) (use gauche.collection) (coerce-to <f64vector> '#(3.1 5.4 3.2)) ⇒ #f64(3.1 5.4 3.2)
{gauche.uvector
}
This procedure creates an uvector of class uvector-class
that shares the storage of the given uniform vector vec.
If optional start and end arguments are given,
only the specified range of vec is used for the new vector.
Since the storage is shared, modification of the original vector
can be seen from the new vector, or vice versa.
The class uvector-class must be either one of the uniform vector class, but is not necessary match the class of the source vector vec. In such case, the new vector looks at the same region of vec’s memory, but interprets it differently. For example, the following code determines whether Gauche is running on big-endian or little-endian machine:
(let ((u8v (uvector-alias <u8vector> #u32(1)))) (if (zero? (u8vector-ref u8v 0)) 'big-endian 'little-endian))
If the uvector-class is other than s8vector or u8vector, the region the new vector points has to meet the alignment requirement. You can assume the beginning of the source vector is aligned suitable for any uniform vectors. So, for example, if you’re creating u32vector from u8vector, the start and end must be multiple of 4 (or, if they’re omitted, the length of the original u8vector must be multiple of 4). An error is signaled when the given parameters doesn’t satisfy alignment constraint.
These are Gauche extension that allows faster arithmetic over uniform vectors, than extracting and calculating element-wise values.
Most procedures comes with two flavors, a functional version (without !
in the name) and a linear-update version (with !
in the name).
A functional version assumes the caller treats the arguments and results immutable objects; mutating them later could have unexpected consequences. (Notably, the functional version may return one of its arguments as is, or returns a pre-computed value, so you shouldn’t assume the return values are freshly allocated objects, unless it is noted so explicitly.)
A linear update version may reuse the storage of the designated argument to produce the return value. Gauche tries to reuse the argument as much as possible, but you should always use the return value and shouldn’t assume the argument itself is modified in-place. In fact, after calling linear-updating procedure, you can’t use the argument that may be modified, since you can’t assume the state of the object after calling the procedure.
{gauche.uvector
}
Element-wise arithmetic. Vec must be a @vector,
and val must be either a @vector, a vector, or a list
of the same length as vec, or a number
(an exact integer for integer vectors,
and a real number for f32- and f64-vectors).
If val is a @vector, its elements are added to, subtracted from, or multiplied by the corresponding elements of vec, respectively, and the results are gathered to a @vector and returned. The linear-update version (those have bang ‘!’ in the name) reuses vec to store the result, and also returns it. If the result of calculation goes out of the range of @vector’s element, the behavior is specified by clamp optional argument. (For f32vector and f64vector, clamp argument is ignored and the result may contain infinity).
If val is a number, it is added to, subtracted from, or multiplied by each element of vec, respectively.
(s8vector-add '#s8(1 2 3 4) '#s8(5 6 7 8)) ⇒ #s8(6 8 10 12)
(u8vector-sub '#u8(1 2 3 4) '#u8(2 2 2 2)) ⇒ error
(u8vector-sub '#u8(1 2 3 4) '#u8(2 2 2 2) 'both) ⇒ #u8(0 0 1 2)
(f32vector-mul '#f32(3.0 2.0 1.0) 1.5) ⇒ #f32(4.5 3.0 1.5)
{gauche.uvector
}
Element-wise division of flonum vectors. These are only defined
for f16, f32 and f64vector. val must be a @vector,
a vector or a list of the same length as vec, or a real number.
(f32vector-div '#f32(1.0 2.0 3.0) 2.0) ⇒ #f32(0.5 1.0 1.5)
{gauche.uvector
}
Element-wise logical (bitwise) operation.
These procedures are only defined for integral vectors.
val must be a @vector, a vector or a list
of the same length as vec,
or an exact integer. Bitwise and, inclusive or or exclusive or
is calculated between each element in vec and the corresponding
element of val (when val is a non-scalar value),
or val itself (when val is an integer).
The result is returned in a @vector.
The linear-update version reuses vec to store the result,
and also returns it.
{gauche.uvector
}
Calculates the dot product of two @vectors.
The length of vec0 and vec1 must be the same.
{gauche.uvector
}
Vec must be a @vector, and each of min and max
must be either a @vector, a vector or a list of the same length
as vec, or a number, or #f
.
For each element in vec, this procedure checks if the value
is between minval and maxval inclusive, where
minval and maxval are the corresponding values of
min and max (when min and/or max is/are
non-scalar value) or min and max themselves (when
min and/or max is/are a number).
When min is #f
, negative infinity is assumed.
When max is #f
, positive infinity is assumed.
If all the elements in vec are within the range, #f
is
returned. Otherwise, the index of the leftmost element of vec
that is out of range is returned.
(u8vector-range-check '#u8(3 1 0 2) 0 3) ⇒ #f (u8vector-range-check '#u8(3 1 0 2) 1 3) ⇒ 2 (u8vector-range-check '#u8(4 32 64 98) 0 '#u8(10 40 70 90)) ⇒ 3 ;; Range check in a program (cond ((u8vector-range-check u8v 1 31) => (lambda (i) (errorf "~sth vector element is out of range: ~s" i (u8vector-ref u8v i)))) (else (do-something u8v)))
{gauche.uvector
}
Vec must be a @vector, and each of min and max
must be either a @vector, a vector or a list of the same length
as vec, or a number, or #f
.
Like @vector-range-check, these procedures check if each element of vec are within the range between minval and maxval inclusive, which are derived from min and max. If the value is less than minval, it is replaced by minval. If the value is grater than maxval, it is replaced by maxval.
@vector-clamp creates a copy of vec and do clamp operation on it, while @vector-clamp! modifies vec. Both return the clamped vector.
(s8vector-clamp '#s8(8 14 -3 -22 0) -10 10) ⇒ #s8(8 10 -3 -10 0)
A uniform vector can be seen as an abstraction of a chunk of memory. So you might want to use it for binary I/O. Yes, you can do it.
{gauche.uvector
}
Reads size elements of uvector of class class from
iport, and returns fleshly created uvector. If iport
is omitted, the curret input port is used.
For example, you can read input as an octet stream as follows:
(with-input-from-string "abcde" (^[] (read-uvector <u8vector> 5))) ⇒ #u8(97 98 99 100 101)
If the input port has already reached EOF, an EOF object is returned. The returned uvector can be shorter than size if the input reaches EOF before size elements are read.
If the iport is a buffered port with ‘modest’ or ‘none’
buffering mode (see File ports), read-uvector
may return
before size elements are read, even if iport
hasn’t reached EOF. The ports connected to a pipe or a network socket
behave so by default.
The data is read as a byte stream, so if you give uniform vectors
other than s8vector or u8vector, your result may affected by
the endianness. If the optional argument endian is
given, the input is interpreted in that endianness.
When omitted, the value of the parameter default-endian
is used. See Endianness, for more about endian handling.
If the size of the input data is unknown and you need to read everything
until EOF, use port->uvector
below.
[R7RS base]
{gauche.uvector
}
Equivalent to (read-uvector <u8vector> size iport)
.
This is an R7RS base procedure.
{gauche.uvector
}
Reads a chunk of data from the given input port iport,
and stores it to the uniform vector vec.
You can give any uniform vector.
If optional start and end
arguments are given, they specify the index range in vec
that is to be filled, and the rest of the vector remains untouched.
Otherwise, entire vector is used. A special value -1 for end
indicates the end of vec.
If iport is omitted, the current input port is used.
If the input reached EOF before the required region of vec is filled, the rest of the vector is untouched.
If iport is already reached EOF when read-uvector!
is
called, an EOF object is returned. Otherwise,
the procedure returns the number of elements read (not bytes).
If the iport is a buffered port with ‘modest’ or ‘none’
buffering mode (see File ports), read-uvector!
may return
before all the elements in vec is filled, even if iport
hasn’t reached EOF. The ports connected to a pipe or a network socket
behave so by default. If you know there will be enough data arriving and
want to make sure vec is filled, change the buffering mode of
iport to ‘full’.
The data is read as a byte stream, so if you give uniform vectors
other than s8vector or u8vector, your result may affected by
the endianness. If the optional argument endian is
given, the input is interpreted in that endianness.
When omitted, the value of the parameter default-endian
is used. See Endianness, for more about endian handling.
{gauche.uvector
}
Deprecated.
An old name of read-uvector!
. Supported for the backward
compatibility, but new code should use read-uvector!
.
{gauche.uvector
}
Read data from the input port iport until EOF and store them
into a uvector of class. If class is omitted,
<u8vector>
is used.
If you specify a class of uvector whose element is more than an octet, the input data is packed with platform’s native byteorder.
This procedure is parallel to port->string
etc.
(see Input utility functions).
[R7RS base]
{gauche.uvector.
}
Similar to read-uvector!
, but bv must be a u8vector.
This is an R7RS base procedure.
{gauche.uvector
}
Writes out the content of the uniform vector vec ’as is’
to the output port oport. If oport is omitted,
the current output port is used.
If optional start and end arguments are given,
they specify the index range in vec to be written out.
A special value -1 for end indicates the end of vec.
This procedure returns an unspecified value.
If you write out a uniform vector except s8vector and u8vector, the
care should be taken about the endianness, as in read-uvector
.
The optional argument endian specifies the output endian.
When it is omitted, the value of the parameter default-endian
is used (see Endianness).
[R7RS vector.@]
{gauche.uvector
}
[R7RS base]
{gauche.uvector
}
Similar to write-uvector
, but bv must be a u8vector.
This is an R7RS base procedure.
{gauche.uvector
}
Deprecated.
An old name of write-uvector
. Supported for the backward
compatibility, but new code should use write-uvector
.
R7RS-small includes bytevectors in its core (scheme.base
).
In Gauche, bytevectors are the same as u8vectors.
The basic R7RS bytevector procedures are provided in this module.
Conversion between bytevectors and strings are provided in
gauche.unicode
(see Unicode transfer encodings)
and srfi.181
(see Transcoded ports).
{gauche.uvector
}
[R7RS base]
Alias of u8vector
. Returns a fresh bytevector (u8vector) with
byte … as its elements.
{gauche.uvector
}
[R7RS base]
Alias of u8vector?
. Returns true iff obj is
a bytevector (u8vector).
{gauche.uvector
}
[R7RS base][R7RS bytevector]
Returns a fresh bytevector (u8vector)
of length len. All elements are initialized by byte
if given.
R7RS base accepts an exact integer between 0 and 255 inclusive as byte. R7RS bytevector extends the range to -128 to 255 inclusive, while the negative value is wrapped-around by modulo 255. This procedure supports the extended range.
{gauche.uvector
}
[R7RS base]
Alias of u8vector-length
. Returns the length of the
bytevector (u8vector) bv.
{gauche.uvector
}
[R7RS base]
Alias of u8vector-ref
and u8vector-set!
.
Read and write k-th element of a bytevector (u8vector) bv.
It is an error to give out-of-bound index.
The return value of bytevector-u8-set!
is unspecified.
As Gauche’s extension, (setter bytevector-u8-ref)
is
bytevector-u8-set!
.
{gauche.uvector
}
[R7RS bytevector]
Like bytevector-u8-ref
and bytevector-u8-set!
, but
treates octets as a signed byte, ranging from -128 to 127, inclusive.
As Gauche’s extension, (setter bytevector-s8-ref)
is
bytevector-s8-set!
.
{gauche.uvector
}
[R7RS base]
Alias of u8vector-copy
. Returns a fresh copy of a
bytevector (u8vector) bv. Optionally you can restrict the
range of the source vector by indices start (inclusive)
and end (exclusive).
{gauche.uvector
}
[R7RS base]
Alias of u8vector-copy!
. Both target and source
muse be bytevectors (u8vectors), and target must be mutable.
Copy the content of source (optionally restricting the range
between indices start (inclusive) and end (exclusive))
into target starting at the index tstart.
{gauche.uvector
}
This is a compatibility procedure for R6RS bytevector-copy!
(hence the suffix -r6
). When R6RS bytevectors are
adpoted as R7RS-large scheme.bytevector
, the R6RS version
of bytevector-copy!
comes into R7RS as well
(hence R7RS has two different bytevector-copy!
, one in
scheme.base
and one in scheme.bytevector
).
It’s unfortunate
that R6RS tends to break tradition and invent a new API; here, the
arguments differ from other *-copy!
procedures:
This procedure copies from src, starting from
sstart and length len, to target starting tstart.
{gauche.uvector
}
[R7RS base]
Alias of u8vector-append
. All arguments must be bytevectors
(u8vectors). Returns a fresh bytevector whose elements are
the concatenation of elements of bv ….
{gauche.uvector
}
[R7RS bytevector]
Alias of u8vector=?
. All arguments must be bytevectors
(u8vectors). Returns #t
iff all bytevectors are of the same
size and content.