class TestCase::GenericType {
  use TestCase::List;
  use Hash;
  
  our $STRING_LIST : cache ro TestCase::List of string;
  
  has strings_list : ro TestCase::List of string;
  
  has string_or_strings : string|string[];
  
  static method basic : int () {
    {
      my $list = (TestCase::List of string)TestCase::List->new(["a", "b"]);
      
      my $elem = $list->get(0);
      
      unless ($elem is_compile_type string) {
        diag; return 0;
      }
      
      unless ($elem eq "a") {
        diag; return 0;
      }
      
    }
    
    {
      my $list = (TestCase::List of TestCase::List of string)TestCase::List->new([TestCase::List->new(["a", "b"]), TestCase::List->new(["c", "d"])]);
      
      my $hash = $list->get(0);
      
      unless ($hash is_compile_type TestCase::List) {
        diag; return 0;
      }
      
      my $value = $hash->get(0);
      
      unless ($value is_compile_type string) {
        diag; return 0;
      }
      
      unless ($value eq "a") {
        diag; return 0;
      }
      
    }
    
    {
      my $self = new TestCase::GenericType;
      
      $self->{strings_list} = TestCase::List->new(["a", "b"]);
      
      my $list = $self->{strings_list};
      
      my $elem = $list->get(0);
      
      unless ($elem is_compile_type string) {
        diag; return 0;
      }
      
      unless ($elem eq "a") {
        diag; return 0;
      }
      
    }
    
    {
      my $self = new TestCase::GenericType;
      
      $self->{strings_list} = TestCase::List->new(["a", "b"]);
      
      my $list = $self->strings_list;
      
      my $elem = $list->get(0);
      
      unless ($elem is_compile_type string) {
        diag; return 0;
      }
      
      unless ($elem eq "a") {
        diag; return 0;
      }
      
    }
    
    # element[]
    {
      {
        my $array = ["a", "b"];
        
        my $list = (TestCase::List of string)TestCase::List->new($array);
        
        my $ret_array = $list->get_array;
        
        unless ($ret_array is_compile_type string[]) {
          diag; return 0;
        }
        
        unless ($ret_array == $array) {
          diag; return 0;
        }
      }
      
      
    }
    
    {
      $STRING_LIST = TestCase::List->new(["a", "b"]);
      
      my $list = $STRING_LIST;
      
      my $elem = $list->get(0);
      
      unless ($elem is_compile_type string) {
        diag; return 0;
      }
      
      unless ($elem eq "a") {
        diag; return 0;
      }
    }
    
    {
      $STRING_LIST = TestCase::List->new(["a", "b"]);
      
      my $list = TestCase::GenericType->STRING_LIST;
      
      my $elem = $list->get(0);
      
      unless ($elem is_compile_type string) {
        diag; return 0;
      }
      
      unless ($elem eq "a") {
        diag; return 0;
      }
    }
    
    {
      my $self = new TestCase::GenericType;
      
      unless ($self->{string_or_strings} is_compile_type object) {
        diag; return 0;
      }
    }
    
    {
      my $var = (string|string[])undef;
      
      unless ($var is_compile_type object) {
        diag; return 0;
      }
    }
    
    {
      my $var : string|string[] = undef;
      
      unless ($var is_compile_type object) {
        diag; return 0;
      }
    }
    
    {
      my $values = (List of Int)List->new;
      
      my $ret = 1 ? $values : undef;
      
      unless ($ret is_compile_type List of Int) {
        diag compile_type_name $ret;
        return 0;
      }
      
    }
    
    return 1;
  }
}
