Iterator-Flex

 view release on metacpan or  search on metacpan

lib/Iterator/Flex/Flatten.pm  view on Meta::CPAN

package Iterator::Flex::Flatten;

# ABSTRACT: Flatten Iterator Class

use v5.28;
use strict;
use warnings;
use experimental 'signatures';

our $VERSION = '0.34';

use Iterator::Flex::Utils qw( STATE RETURN EXHAUSTION :IterAttrs :IterStates throw_failure);
use Iterator::Flex::Factory 'construct_from_iterable', 'to_iterator';
use Ref::Util 'is_plain_arrayref', 'is_plain_hashref', 'is_blessed_ref';
use parent 'Iterator::Flex::Base';

use namespace::clean;

















































sub new ( $class, $iterable, $pars = {} ) {
    $class->SUPER::new( { src => $iterable }, $pars );
}

## no critic( ExcessComplexity )
sub construct ( $class, $state ) {

    throw_failure( parameter => q{'state' parameter must be a HASH reference} )
      unless Ref::Util::is_hashref( $state );

    my ( $prev, $current, $idx, $iter )
      = @{$state}{qw[ prev current idx iter src ]};

    my $src = @{$state}{qw[ code src ]};

    $src = to_iterator( $src );

    my $self;
    my $iterator_state;

    my $is_exhausted      = $src->can( 'is_exhausted' );
    my $iter_is_exhausted = is_blessed_ref( $iter )
      && $iter->can( 'is_exhausted' );

    my $rewind = !!0;
    my $reset  = !!0;

    return {
        ( +_NAME ) => 'iflatten',

        ( +_SELF ) => \$self,

        ( +STATE ) => \$iterator_state,

        ( +PREV ) => sub {
            return $prev;
        },

        ( +CURRENT ) => sub {
            return $current;
        },

        ( +NEXT ) => sub {
            return $self->signal_exhaustion if $iterator_state == IterState_EXHAUSTED;

            my $value;

          LOOP:
            while ( 1 ) {

                if ( !defined $iter ) {

                    $value = $src->();
                    if ( !defined $value && $src->$is_exhausted ) {
                        $prev    = $current;
                        $current = undef;
                        return $self->signal_exhaustion;
                    }

                    # most likely
                    last LOOP
                      if !ref $value || is_plain_hashref( $value );

                    # handle arrays directly; could use an iterator, but this is
                    # faster
                    if ( is_plain_arrayref( $value ) ) {
                        $iter = $value;
                        $idx  = 0;
                    }



( run in 0.806 second using v1.01-cache-2.11-cpan-99c4e6809bf )