aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator')
-rw-r--r--erts/emulator/beam/bif.c72
-rw-r--r--erts/emulator/beam/bif.tab2
-rw-r--r--erts/emulator/test/tuple_SUITE.erl45
3 files changed, 119 insertions, 0 deletions
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
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),