Source file test/typeparam/list.go

     1  // run
     2  
     3  // Copyright 2021 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  package main
     8  
     9  import (
    10  	"fmt"
    11  )
    12  
    13  type Ordered interface {
    14  	~int | ~int8 | ~int16 | ~int32 | ~int64 |
    15  		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
    16  		~float32 | ~float64 |
    17  		~string
    18  }
    19  
    20  // _List is a linked list of ordered values of type T.
    21  type _List[T Ordered] struct {
    22  	next *_List[T]
    23  	val  T
    24  }
    25  
    26  func (l *_List[T]) Largest() T {
    27  	var max T
    28  	for p := l; p != nil; p = p.next {
    29  		if p.val > max {
    30  			max = p.val
    31  		}
    32  	}
    33  	return max
    34  }
    35  
    36  type OrderedNum interface {
    37  	~int | ~int8 | ~int16 | ~int32 | ~int64 |
    38  		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
    39  		~float32 | ~float64
    40  }
    41  
    42  // _ListNum is a linked _List of ordered numeric values of type T.
    43  type _ListNum[T OrderedNum] struct {
    44  	next *_ListNum[T]
    45  	val  T
    46  }
    47  
    48  const Clip = 5
    49  
    50  // clippedLargest returns the largest in the list of OrderNums, but a max of 5.
    51  // Test use of untyped constant in an expression with a generically-typed parameter
    52  func (l *_ListNum[T]) ClippedLargest() T {
    53  	var max T
    54  	for p := l; p != nil; p = p.next {
    55  		if p.val > max && p.val < Clip {
    56  			max = p.val
    57  		}
    58  	}
    59  	return max
    60  }
    61  
    62  func main() {
    63  	i3 := &_List[int]{nil, 1}
    64  	i2 := &_List[int]{i3, 3}
    65  	i1 := &_List[int]{i2, 2}
    66  	if got, want := i1.Largest(), 3; got != want {
    67  		panic(fmt.Sprintf("got %d, want %d", got, want))
    68  	}
    69  
    70  	b3 := &_List[byte]{nil, byte(1)}
    71  	b2 := &_List[byte]{b3, byte(3)}
    72  	b1 := &_List[byte]{b2, byte(2)}
    73  	if got, want := b1.Largest(), byte(3); got != want {
    74  		panic(fmt.Sprintf("got %d, want %d", got, want))
    75  	}
    76  
    77  	f3 := &_List[float64]{nil, 13.5}
    78  	f2 := &_List[float64]{f3, 1.2}
    79  	f1 := &_List[float64]{f2, 4.5}
    80  	if got, want := f1.Largest(), 13.5; got != want {
    81  		panic(fmt.Sprintf("got %f, want %f", got, want))
    82  	}
    83  
    84  	s3 := &_List[string]{nil, "dd"}
    85  	s2 := &_List[string]{s3, "aa"}
    86  	s1 := &_List[string]{s2, "bb"}
    87  	if got, want := s1.Largest(), "dd"; got != want {
    88  		panic(fmt.Sprintf("got %s, want %s", got, want))
    89  	}
    90  
    91  	j3 := &_ListNum[int]{nil, 1}
    92  	j2 := &_ListNum[int]{j3, 32}
    93  	j1 := &_ListNum[int]{j2, 2}
    94  	if got, want := j1.ClippedLargest(), 2; got != want {
    95  		panic(fmt.Sprintf("got %d, want %d", got, want))
    96  	}
    97  	g3 := &_ListNum[float64]{nil, 13.5}
    98  	g2 := &_ListNum[float64]{g3, 1.2}
    99  	g1 := &_ListNum[float64]{g2, 4.5}
   100  	if got, want := g1.ClippedLargest(), 4.5; got != want {
   101  		panic(fmt.Sprintf("got %f, want %f", got, want))
   102  	}
   103  }
   104  

View as plain text