From be410cc32ae0eefb53df1d92a3ff576628771075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Sat, 10 Sep 2011 03:02:34 +0200 Subject: Add insert_element/3 and delete_element/2 * erlang:insert_element/3 - extend a tuple at an index * erlang:delete_element/2 - remove an element at an index --- erts/emulator/beam/bif.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ erts/emulator/beam/bif.tab | 2 ++ 2 files changed, 74 insertions(+) diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index c4ff4fe982..97c8114437 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -2526,6 +2526,78 @@ BIF_RETTYPE append_element_2(BIF_ALIST_2) BIF_RET(res); } +BIF_RETTYPE insert_element_3(BIF_ALIST_3) +{ + Eterm* ptr; + Eterm* hp; + Uint arity; + Eterm res; + Sint ix; + + if (is_not_tuple(BIF_ARG_2) || is_not_small(BIF_ARG_1)) { + BIF_ERROR(BIF_P, BADARG); + } + + ptr = tuple_val(BIF_ARG_2); + arity = arityval(*ptr); + ix = signed_val(BIF_ARG_1); + + if ((ix < 1) || (ix > (arity + 1))) { + BIF_ERROR(BIF_P, BADARG); + } + + hp = HAlloc(BIF_P, arity + 1 + 1); + res = make_tuple(hp); + *hp = make_arityval(arity + 1); + + ix--; + arity -= ix; + + while (ix--) { *++hp = *++ptr; } + + *++hp = BIF_ARG_3; + + while(arity--) { *++hp = *++ptr; } + + BIF_RET(res); +} + +BIF_RETTYPE delete_element_2(BIF_ALIST_3) +{ + Eterm* ptr; + Eterm* hp; + Uint arity; + Eterm res; + Sint ix; + + if (is_not_tuple(BIF_ARG_2) || is_not_small(BIF_ARG_1)) { + BIF_ERROR(BIF_P, BADARG); + } + + ptr = tuple_val(BIF_ARG_2); + arity = arityval(*ptr); + ix = signed_val(BIF_ARG_1); + + if ((ix < 1) || (ix > arity) || (arity == 0)) { + BIF_ERROR(BIF_P, BADARG); + } + + hp = HAlloc(BIF_P, arity + 1 - 1); + res = make_tuple(hp); + *hp = make_arityval(arity - 1); + + ix--; + arity -= ix; + + while (ix--) { *++hp = *++ptr; } + + ++ptr; + + while(arity--) { *++hp = *++ptr; } + + BIF_RET(res); +} + /**********************************************************************/ /* convert an atom to a list of ascii integer */ diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab index 9a1a25031c..1799f15504 100644 --- a/erts/emulator/beam/bif.tab +++ b/erts/emulator/beam/bif.tab @@ -821,6 +821,8 @@ bif erlang:dt_append_vm_tag_data/1 # bif erlang:prepare_loading/2 bif erlang:finish_loading/1 +bif erlang:insert_element/3 +bif erlang:delete_element/2 # # Obsolete -- cgit v1.2.3 From a190a366c5e6f9ff7abab12e51167d07d51ee417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Wed, 28 Nov 2012 15:24:20 +0100 Subject: tests: Update tuple_SUITE for insert and delete * Test erlang:insert_element/3 BIF * Test erlang:delete_element/2 BIF --- erts/emulator/test/tuple_SUITE.erl | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/erts/emulator/test/tuple_SUITE.erl b/erts/emulator/test/tuple_SUITE.erl index 978d96a110..a3b2764a5d 100644 --- a/erts/emulator/test/tuple_SUITE.erl +++ b/erts/emulator/test/tuple_SUITE.erl @@ -20,6 +20,7 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, t_size/1, t_tuple_size/1, t_element/1, t_setelement/1, + t_insert_element/1, t_delete_element/1, t_list_to_tuple/1, t_tuple_to_list/1, t_make_tuple_2/1, t_make_tuple_3/1, t_append_element/1, build_and_match/1, tuple_with_case/1, tuple_in_guard/1]). @@ -41,6 +42,7 @@ all() -> [build_and_match, t_size, t_tuple_size, t_list_to_tuple, t_tuple_to_list, t_element, t_setelement, t_make_tuple_2, t_make_tuple_3, t_append_element, + t_insert_element, t_delete_element, tuple_with_case, tuple_in_guard]. groups() -> @@ -262,6 +264,49 @@ t_make_tuple_3(Config) when is_list(Config) -> ok. +%% Tests the erlang:insert_element/3 BIF. +t_insert_element(Config) when is_list(Config) -> + {a} = erlang:insert_element(1, {}, a), + {{b,b},a} = erlang:insert_element(1, {a}, {b,b}), + {a,b} = erlang:insert_element(2, {a}, b), + [b,def|_] = tuple_to_list(erlang:insert_element(1, erlang:make_tuple(1 bsl 20, def), b)), + [def,b|_] = tuple_to_list(erlang:insert_element(2, erlang:make_tuple(1 bsl 20, def), b)), + [def,b|_] = lists:reverse(tuple_to_list(erlang:insert_element(1 bsl 20, erlang:make_tuple(1 bsl 20, def), b))), + [b,def|_] = lists:reverse(tuple_to_list(erlang:insert_element((1 bsl 20) + 1, erlang:make_tuple(1 bsl 20, def), b))), + + %% Error cases. + {'EXIT',{badarg,_}} = (catch erlang:insert_element(1, [], a)), + {'EXIT',{badarg,_}} = (catch erlang:insert_element(1, a, a)), + {'EXIT',{badarg,_}} = (catch erlang:insert_element(0, {}, a)), + {'EXIT',{badarg,_}} = (catch erlang:insert_element(0, {b,b,b,b,b}, a)), + {'EXIT',{badarg,_}} = (catch erlang:insert_element(-1, {}, a)), + {'EXIT',{badarg,_}} = (catch erlang:insert_element(2, {}, a)), + {'EXIT',{badarg,_}} = (catch erlang:insert_element(6, {b,b,b,b}, a)), + {'EXIT',{badarg,_}} = (catch erlang:insert_element(1 bsl 20, {b,b,b,b}, a)), + ok. + +%% Tests the erlang:delete_element/3 BIF. +t_delete_element(Config) when is_list(Config) -> + {} = erlang:delete_element(1, {a}), + {{b,b},c} = erlang:delete_element(1, {a,{b,b},c}), + {a,b} = erlang:delete_element(2, {a,c,b}), + [2,3|_] = tuple_to_list(erlang:delete_element(1, list_to_tuple(lists:seq(1, 1 bsl 20)))), + [1,3|_] = tuple_to_list(erlang:delete_element(2, list_to_tuple(lists:seq(1, 1 bsl 20)))), + [(1 bsl 20) - 1, (1 bsl 20) - 2 |_] = lists:reverse(tuple_to_list(erlang:delete_element(1 bsl 20, list_to_tuple(lists:seq(1, 1 bsl 20))))), + [(1 bsl 20), (1 bsl 20) - 2 |_] = lists:reverse(tuple_to_list(erlang:delete_element((1 bsl 20) - 1, list_to_tuple(lists:seq(1, 1 bsl 20))))), + + %% Error cases. + {'EXIT',{badarg,_}} = (catch erlang:delete_element(1, [])), + {'EXIT',{badarg,_}} = (catch erlang:delete_element(1, a)), + {'EXIT',{badarg,_}} = (catch erlang:delete_element(0, {})), + {'EXIT',{badarg,_}} = (catch erlang:delete_element(-1, {})), + {'EXIT',{badarg,_}} = (catch erlang:delete_element(1, {})), + {'EXIT',{badarg,_}} = (catch erlang:delete_element(0, {b,b,b,b,b})), + {'EXIT',{badarg,_}} = (catch erlang:delete_element(5, {b,b,b,b})), + {'EXIT',{badarg,_}} = (catch erlang:delete_element(1 bsl 20, {b,c,b,b,b})), + ok. + + %% Tests the append_element/2 BIF. t_append_element(Config) when is_list(Config) -> ok = t_append_element({}, 2048, 2048), -- cgit v1.2.3 From 571803ae686c226ad1db4c54c7a6d2b579b9ba9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Wed, 28 Nov 2012 16:15:26 +0100 Subject: erts: Document insert_element and delete_element Document new BIFs: * erlang:insert_element/3 * erlang:delete_element/2 --- erts/doc/src/erlang.xml | 34 ++++++++++++++++++++++++++++++++++ erts/preloaded/src/erlang.erl | 19 +++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index 1a97a84b42..2faa46d760 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -626,6 +626,22 @@ false {more,6} + + + + Delete element at index in a tuple + 1..tuple_size(Tuple1) + +

+ Returns a new tuple with element at Index removed from + tuple Tuple1. +

+
+> erlang:delete_element(2, {one, two, three}).
+{one,three}
+
+
+ Make the current code for a module old @@ -1361,6 +1377,24 @@ os_prompt% when the process wakes up.

+ + + + Insert an element at index in a tuple + 1..tuple_size(Tuple1) + 1 + +

+ Returns a new tuple with element Term insert at position + Index in tuple Tuple1. + All elements from position Index and upwards are subsequently + pushed one step higher in the new tuple Tuple2. +

+
+> erlang:insert_element(2, {one, two, three}, new).
+{one,new,two,three}
+
+
+ Text representation of an integer diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl index 51a190b095..739fdde10a 100644 --- a/erts/preloaded/src/erlang.erl +++ b/erts/preloaded/src/erlang.erl @@ -79,6 +79,7 @@ -export([bump_reductions/1, byte_size/1, call_on_load_function/1]). -export([cancel_timer/1, check_old_code/1, check_process_code/2, crc32/1]). -export([crc32/2, crc32_combine/3, date/0, decode_packet/3]). +-export([delete_element/2]). -export([delete_module/1, demonitor/1, demonitor/2, display/1]). -export([display_nl/0, display_string/1, dist_exit/3, erase/0, erase/1]). -export([error/1, error/2, exit/1, exit/2, external_size/1]). @@ -88,6 +89,7 @@ -export([garbage_collect_message_area/0, get/0, get/1, get_keys/1]). -export([get_module_info/1, get_stacktrace/0, group_leader/0]). -export([group_leader/2, halt/0, halt/1, halt/2, hash/2, hibernate/3]). +-export([insert_element/3]). -export([integer_to_list/1, iolist_size/1, iolist_to_binary/1]). -export([is_alive/0, is_builtin/3, is_process_alive/1, length/1, link/1]). -export([list_to_atom/1, list_to_binary/1, list_to_bitstr/1]). @@ -529,6 +531,14 @@ date() -> decode_packet(_Type, _Bin, _Options) -> erlang:nif_error(undefined). +%% delete_element/2 +-spec erlang:delete_element(Index, Tuple1) -> Tuple2 when + Index :: pos_integer(), + Tuple1 :: tuple(), + Tuple2 :: tuple(). +delete_element(_Index, _Tuple1) -> + erlang:nif_error(undefined). + %% delete_module/1 -spec delete_module(Module) -> true | undefined when Module :: module(). @@ -820,6 +830,15 @@ hash(_Term, _Range) -> hibernate(_Module, _Function, _Args) -> erlang:nif_error(undefined). +%% insert_element/3 +-spec erlang:insert_element(Index, Tuple1, Term) -> Tuple2 when + Index :: pos_integer(), + Tuple1 :: tuple(), + Tuple2 :: tuple(), + Term :: term(). +insert_element(_Index, _Tuple1, _Term) -> + erlang:nif_error(undefined). + %% integer_to_list/1 -spec integer_to_list(Integer) -> string() when Integer :: integer(). -- cgit v1.2.3 From fb5751c105609baa95e668a25a9122e2c0c000bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Fri, 14 Dec 2012 16:17:39 +0100 Subject: Update preloaded erlang.beam --- erts/preloaded/ebin/erlang.beam | Bin 92280 -> 92736 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam index 074e31fb13..b59c22eb02 100644 Binary files a/erts/preloaded/ebin/erlang.beam and b/erts/preloaded/ebin/erlang.beam differ -- cgit v1.2.3