#!./perl

BEGIN {
    chdir 't' if -d 't';
    require './test.pl';
    set_up_inc('../lib');
}

plan tests => 26;

is(reverse("abc"), "cba", 'simple reverse');

$_ = "foobar";
is(reverse(), "raboof", 'reverse of the default variable');

{
    my @a = ("foo", "bar");
    my @b = reverse @a;

    is($b[0], $a[1], 'array reversal moved second element to first');
    is($b[1], $a[0], 'array reversal moved first element to second');
}

{
    my @a = (1, 2, 3, 4);
    @a = reverse @a;
    is("@a", "4 3 2 1", 'four element array reversed');

    delete $a[1];
    @a = reverse @a;
    ok(!exists $a[2], 'array reversed with deleted second element');
    is($a[0] . $a[1] . $a[3], '124', 'remaining elements ok after delete and reverse');

    @a = (5, 6, 7, 8, 9);
    @a = reverse @a;
    is("@a", "9 8 7 6 5", 'five element array reversed');

    delete $a[3];
    @a = reverse @a;
    ok(!exists $a[1], 'five element array reversed with deleted fourth element');
    is($a[0] . $a[2] . $a[3] . $a[4], '5789', 'remaining elements ok after delete and reverse');

    delete $a[2];
    @a = reverse @a;
    ok(!exists $a[2] && !exists $a[3], 'test position of two deleted elements after reversal');
    is($a[0] . $a[1] . $a[4], '985', 'check value of remaining elements');

    my @empty;
    @empty = reverse @empty;
    is("@empty", "", 'reversed empty array is still empty');
}

use Tie::Array;

{
    tie my @a, 'Tie::StdArray';

    @a = (1, 2, 3, 4);
    @a = reverse @a;
    is("@a", "4 3 2 1", 'tie array reversal');

    delete $a[1];
    @a = reverse @a;
    ok(!exists $a[2], 'deleted element position ok after reversal of tie array');
    is($a[0] . $a[1] . $a[3], '124', 'remaining elements ok after delete and reversal for tie array');

    @a = (5, 6, 7, 8, 9);
    @a = reverse @a;
    is("@a", "9 8 7 6 5", 'five element tie array reversal');

    delete $a[3];
    @a = reverse @a;
    ok(!exists $a[1], 'deleted element position ok after tie array reversal');
    is($a[0] . $a[2] . $a[3] . $a[4], '5789', 'remaining elements ok after tie array delete and reversal');

    delete $a[2];
    @a = reverse @a;
    ok(!exists $a[2] && !exists $a[3], 'two deleted element positions ok after tie array reversal');
    is($a[0] . $a[1] . $a[4], '985', 'remaining elements ok after two deletes and reversals');

    tie my @empty, "Tie::StdArray";
    @empty = reverse @empty;
    is(scalar(@empty), 0, 'reversed tie array still empty after reversal');
}

{
    # Unicode.

    my $a = "\x{263A}\x{263A}x\x{263A}y\x{263A}";
    my $b = scalar reverse($a);
    my $c = scalar reverse($b);
    is($a, $c, 'Unicode string double reversal matches original');
}

# in-place reversing of weak references
SKIP: {
    skip_if_miniperl("no dynamic loading on miniperl, no extension Scalar::Util", 2);
    require Scalar::Util;
    my @a = map { \(my $dummy = $_) } 1..5; # odd number of elements
    my @r = @a[0,2];                        # middle and non-middle element
    Scalar::Util::weaken($a[0]);
    Scalar::Util::weaken($a[2]);
    @a = reverse @a;
    @r = ();
    ok defined $a[-1] && ${$a[-1]} eq '1', "in-place reverse strengthens weak reference";
    ok defined $a[2] && ${$a[2]} eq '3', "in-place reverse strengthens weak reference in the middle";
}

# [perl #132544] stack pointer used to go wild when nullary reverse
# required extending the stack
for(0..1000){()=(0..$_,scalar reverse )}
pass "extending the stack without crashing";
