[ Non-logical Variables, Arrays, Bags, Shelves and Stores | Reference Manual | Alphabetic Index ]

# shelf_test_and_set(+ShelfHandle, +Index, +Expected, ?NewValue)

Replace a given term in a shelf object

ShelfHandle
  A shelf handle or shelf name
Index
  An integer
Expected
  An arbitrary term
NewValue
  An arbitrary term

## Description

This is an atomic operation for replacing a given old shelf value with a new one. If the shelf slot does not contain the expected old value, the predicate fails without changing anything. It is a shorthand for:

    	shelf_test_and_set(ShelfHandle, Index, Expected, New) :-
    	    with_mutex(ShelfHandle, (
    		shelf_get(ShelfHandle, Index, Old),
    		Old == Expected,
    		shelf_set(ShelfHandle, Index, New)
    	    ).

For details on shelf_get/3 and shelf_set/3, see there.

Note that this can never succeed if Expected is not ground.

### Modes and Determinism

- shelf_test_and_set(+, +, +, ?) is semidet

### Exceptions

(4) instantiation fault
  ShelfHandle is not instantiated
(5) type error
  Index is not instantiated
(5) type error
  ShelfHandle is not a shelf
(5) type error
  Index is not an integer
(6) out of range
  Index is negative or greater than the number of slots on the shelf
(40) stale object handle
  ShelfHandle refers to an already destroyed shelf

## Examples

        	?- shelf_create(s(old),S), shelf_test_and_set(S,1,old,new), shelf_get(S,1,New).

    	S = $&(shelf,"36nzz7")
    	New = new
    	Yes (0.00s cpu)

    	?- shelf_create(s(old),S), shelf_test_and_set(S,1,foo,new), shelf_get(S,1,New).

    	No (0.00s cpu)

## See Also

shelf_create / 2, shelf_create / 3, shelf_get / 3, shelf_set / 3, struct / 1