4
4
//! default).
5
5
6
6
use std:: cmp:: max;
7
- use std :: ops :: Index ;
7
+ use core :: marker :: PhantomData ;
8
8
9
9
use approx:: { AbsDiffEq , RelativeEq , UlpsEq } ;
10
10
use num_traits:: { One , Zero } ;
@@ -16,55 +16,13 @@ use crate::{from_f64, FromF64};
16
16
#[ cfg( feature = "named_gradients" ) ]
17
17
pub mod named;
18
18
19
- /// Types which represent an ordered collection of known size
20
- pub trait ArrayLike : Index < usize > {
21
- /// Returns the number of elements in the collection, also referred to as its 'length'.
22
- fn len ( & self ) -> usize ;
23
- /// Returns a reference to the element at the position i or None if out of bounds.
24
- fn get ( & self , i : usize ) -> Option < & Self :: Output > ;
25
- /// Returns a pointer to the first element of the collection, or None if it is empty.
26
- fn first ( & self ) -> Option < & Self :: Output > {
27
- self . get ( 0 )
28
- }
29
- /// Returns a pointer to the last element of the collection, or None if it is empty.
30
- fn last ( & self ) -> Option < & Self :: Output > {
31
- if !self . is_empty ( ) {
32
- self . get ( self . len ( ) - 1 )
33
- } else {
34
- None
35
- }
36
- }
37
- /// Returns true if the collection contains no elements.
38
- fn is_empty ( & self ) -> bool {
39
- self . len ( ) == 0
40
- }
41
- }
42
-
43
- impl < T > ArrayLike for Vec < T > {
44
- fn len ( & self ) -> usize {
45
- self . len ( )
46
- }
47
- fn get ( & self , i : usize ) -> Option < & T > {
48
- self . as_slice ( ) . get ( i)
49
- }
50
- }
51
-
52
- impl < T , const N : usize > ArrayLike for [ T ; N ] {
53
- fn len ( & self ) -> usize {
54
- <[ T ] >:: len ( self )
55
- }
56
- fn get ( & self , i : usize ) -> Option < & T > {
57
- <[ T ] >:: get ( self , i)
58
- }
59
- }
60
-
61
19
impl < C , T > From < T > for Gradient < C , T >
62
20
where
63
21
C : Mix + Clone ,
64
- T : ArrayLike < Output = ( C :: Scalar , C ) >
22
+ T : AsRef < [ ( C :: Scalar , C ) ] >
65
23
{
66
24
fn from ( col : T ) -> Self {
67
- Gradient ( col)
25
+ Gradient ( col, PhantomData )
68
26
}
69
27
}
70
28
@@ -77,21 +35,22 @@ where
77
35
/// the domain of the gradient will have the same color as the closest control
78
36
/// point.
79
37
#[ derive( Clone , Debug ) ]
80
- pub struct Gradient < C , T = Vec < ( <C as Mix >:: Scalar , C ) > > ( T )
38
+ pub struct Gradient < C , T = Vec < ( <C as Mix >:: Scalar , C ) > > ( T , PhantomData < C > )
81
39
where
82
40
C : Mix + Clone ,
83
- T : ArrayLike < Output = ( C :: Scalar , C ) > ;
41
+ T : AsRef < [ ( C :: Scalar , C ) ] > ;
84
42
85
43
impl < C , T > Gradient < C , T >
86
44
where
87
45
C : Mix + Clone ,
88
- T : ArrayLike < Output = ( C :: Scalar , C ) >
46
+ T : AsRef < [ ( C :: Scalar , C ) ] >
89
47
{
90
48
/// Get a color from the gradient. The color of the closest control point
91
49
/// will be returned if `i` is outside the domain.
92
50
pub fn get ( & self , i : C :: Scalar ) -> C {
93
51
let & ( mut min, ref min_color) = self
94
52
. 0
53
+ . as_ref ( )
95
54
. get ( 0 )
96
55
. expect ( "a Gradient must contain at least one color" ) ;
97
56
let mut min_color = min_color;
@@ -103,10 +62,11 @@ where
103
62
104
63
let & ( mut max, ref max_color) = self
105
64
. 0
65
+ . as_ref ( )
106
66
. last ( )
107
67
. expect ( "a Gradient must contain at least one color" ) ;
108
68
let mut max_color = max_color;
109
- let mut max_index = self . 0 . len ( ) - 1 ;
69
+ let mut max_index = self . 0 . as_ref ( ) . len ( ) - 1 ;
110
70
111
71
if i >= max {
112
72
return max_color. clone ( ) ;
115
75
while min_index < max_index - 1 {
116
76
let index = min_index + ( max_index - min_index) / 2 ;
117
77
118
- let ( p, ref color) = self . 0 [ index] ;
78
+ let ( p, ref color) = self . 0 . as_ref ( ) [ index] ;
119
79
120
80
if i <= p {
121
81
max = p;
@@ -137,10 +97,10 @@ where
137
97
/// be at least one color and they are expected to be ordered by their
138
98
/// position value.
139
99
pub fn with_domain ( colors : T ) -> Gradient < C , T > {
140
- assert ! ( !colors. is_empty( ) ) ;
100
+ assert ! ( !colors. as_ref ( ) . is_empty( ) ) ;
141
101
142
102
//Maybe sort the colors?
143
- Gradient ( colors)
103
+ Gradient ( colors, PhantomData )
144
104
}
145
105
146
106
/// Take `n` evenly spaced colors from the gradient, as an iterator. The
@@ -196,10 +156,12 @@ where
196
156
pub fn domain ( & self ) -> ( C :: Scalar , C :: Scalar ) {
197
157
let & ( min, _) = self
198
158
. 0
159
+ . as_ref ( )
199
160
. get ( 0 )
200
161
. expect ( "a Gradient must contain at least one color" ) ;
201
162
let & ( max, _) = self
202
163
. 0
164
+ . as_ref ( )
203
165
. last ( )
204
166
. expect ( "a Gradient must contain at least one color" ) ;
205
167
( min, max)
@@ -221,7 +183,7 @@ impl<C: Mix + Clone> Gradient<C> {
221
183
* p = from_f64 :: < C :: Scalar > ( i as f64 ) * step_size;
222
184
}
223
185
224
- Gradient ( points)
186
+ Gradient ( points, PhantomData )
225
187
}
226
188
}
227
189
@@ -230,7 +192,7 @@ impl<C: Mix + Clone> Gradient<C> {
230
192
pub struct Take < ' a , C , T = Vec < ( <C as Mix >:: Scalar , C ) > >
231
193
where
232
194
C : Mix + Clone + ' a ,
233
- T : ArrayLike < Output = ( C :: Scalar , C ) >
195
+ T : AsRef < [ ( C :: Scalar , C ) ] >
234
196
{
235
197
gradient : MaybeSlice < ' a , C , T > ,
236
198
from : C :: Scalar ,
@@ -244,7 +206,7 @@ impl<'a, C, T> Iterator for Take<'a, C, T>
244
206
where
245
207
C :: Scalar : FromF64 ,
246
208
C : Mix + Clone ,
247
- T : ArrayLike < Output = ( C :: Scalar , C ) >
209
+ T : AsRef < [ ( C :: Scalar , C ) ] >
248
210
{
249
211
type Item = C ;
250
212
@@ -277,14 +239,14 @@ impl<'a, C, T> ExactSizeIterator for Take<'a, C, T>
277
239
where
278
240
C :: Scalar : FromF64 ,
279
241
C : Mix + Clone ,
280
- T : ArrayLike < Output = ( C :: Scalar , C ) >
242
+ T : AsRef < [ ( C :: Scalar , C ) ] >
281
243
{ }
282
244
283
245
impl < ' a , C , T > DoubleEndedIterator for Take < ' a , C , T >
284
246
where
285
247
C :: Scalar : FromF64 ,
286
248
C : Mix + Clone ,
287
- T : ArrayLike < Output = ( C :: Scalar , C ) >
249
+ T : AsRef < [ ( C :: Scalar , C ) ] >
288
250
{
289
251
fn next_back ( & mut self ) -> Option < Self :: Item > {
290
252
if self . from_head + self . from_end < self . len {
@@ -309,7 +271,7 @@ where
309
271
pub struct Slice < ' a , C , T = Vec < ( <C as Mix >:: Scalar , C ) > >
310
272
where
311
273
C : Mix + Clone + ' a ,
312
- T : ArrayLike < Output = ( C :: Scalar , C ) >
274
+ T : AsRef < [ ( C :: Scalar , C ) ] >
313
275
{
314
276
gradient : & ' a Gradient < C , T > ,
315
277
range : Range < C :: Scalar > ,
@@ -318,7 +280,7 @@ where
318
280
impl < ' a , C , T > Slice < ' a , C , T >
319
281
where
320
282
C : Mix + Clone + ' a ,
321
- T : ArrayLike < Output = ( C :: Scalar , C ) >
283
+ T : AsRef < [ ( C :: Scalar , C ) ] >
322
284
{
323
285
/// Get a color from the gradient slice. The color of the closest domain
324
286
/// limit will be returned if `i` is outside the domain.
@@ -353,7 +315,7 @@ where
353
315
impl < ' a , C , T > Slice < ' a , C , T >
354
316
where
355
317
C : Mix + Clone + ' a ,
356
- T : ArrayLike < Output = ( C :: Scalar , C ) > + Clone
318
+ T : AsRef < [ ( C :: Scalar , C ) ] > + Clone
357
319
{
358
320
/// Take `n` evenly spaced colors from the gradient slice, as an iterator.
359
321
pub fn take ( & self , n : usize ) -> Take < C , T > {
@@ -544,7 +506,7 @@ where
544
506
enum MaybeSlice < ' a , C , T = Vec < ( <C as Mix >:: Scalar , C ) > >
545
507
where
546
508
C : Mix + Clone + ' a ,
547
- T : ArrayLike < Output = ( C :: Scalar , C ) >
509
+ T : AsRef < [ ( C :: Scalar , C ) ] >
548
510
{
549
511
NotSlice ( & ' a Gradient < C , T > ) ,
550
512
Slice ( Slice < ' a , C , T > ) ,
@@ -553,7 +515,7 @@ where
553
515
impl < ' a , C , T > MaybeSlice < ' a , C , T >
554
516
where
555
517
C : Mix + Clone + ' a ,
556
- T : ArrayLike < Output = ( C :: Scalar , C ) >
518
+ T : AsRef < [ ( C :: Scalar , C ) ] >
557
519
{
558
520
fn get ( & self , i : C :: Scalar ) -> C {
559
521
match * self {
0 commit comments