Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package render | 5 package render |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "bytes" | 8 "bytes" |
| 9 "fmt" | 9 "fmt" |
| 10 "reflect" | 10 "reflect" |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 323 | 323 |
| 324 default: | 324 default: |
| 325 buf.WriteString(t.String()) | 325 buf.WriteString(t.String()) |
| 326 } | 326 } |
| 327 | 327 |
| 328 if parens { | 328 if parens { |
| 329 buf.WriteRune(')') | 329 buf.WriteRune(')') |
| 330 } | 330 } |
| 331 } | 331 } |
| 332 | 332 |
| 333 type cmpFn func(a, b reflect.Value) int | |
| 334 | |
| 333 type sortableValueSlice struct { | 335 type sortableValueSlice struct { |
| 334 » kind reflect.Kind | 336 » cmp cmpFn |
| 335 elements []reflect.Value | 337 elements []reflect.Value |
| 336 } | 338 } |
| 337 | 339 |
| 338 func (s *sortableValueSlice) Len() int { | 340 func (s sortableValueSlice) Len() int { |
| 339 return len(s.elements) | 341 return len(s.elements) |
| 340 } | 342 } |
| 341 | 343 |
| 342 func (s *sortableValueSlice) Less(i, j int) bool { | 344 func (s sortableValueSlice) Less(i, j int) bool { |
| 343 » switch s.kind { | 345 » return s.cmp(s.elements[i], s.elements[j]) < 0 |
| 344 » case reflect.String: | |
| 345 » » return s.elements[i].String() < s.elements[j].String() | |
| 346 | |
| 347 » case reflect.Int: | |
| 348 » » return s.elements[i].Int() < s.elements[j].Int() | |
| 349 | |
| 350 » default: | |
| 351 » » panic(fmt.Errorf("unsupported sort kind: %s", s.kind)) | |
| 352 » } | |
| 353 } | 346 } |
| 354 | 347 |
| 355 func (s *sortableValueSlice) Swap(i, j int) { | 348 func (s sortableValueSlice) Swap(i, j int) { |
| 356 s.elements[i], s.elements[j] = s.elements[j], s.elements[i] | 349 s.elements[i], s.elements[j] = s.elements[j], s.elements[i] |
| 357 } | 350 } |
| 358 | 351 |
| 352 func cmpForType(t reflect.Type) cmpFn { | |
|
dnj
2016/02/19 19:31:10
nit: document that this specifically aims to opera
iannucci
2016/02/19 21:18:28
Done.
| |
| 353 switch t.Kind() { | |
| 354 case reflect.String: | |
| 355 return func(av, bv reflect.Value) int { | |
| 356 a, b := av.String(), bv.String() | |
| 357 if a < b { | |
| 358 return -1 | |
| 359 } else if a > b { | |
| 360 return 1 | |
| 361 } | |
| 362 return 0 | |
| 363 } | |
| 364 | |
| 365 case reflect.Bool: | |
| 366 return func(av, bv reflect.Value) int { | |
| 367 a, b := av.Bool(), bv.Bool() | |
| 368 if !a && b { | |
| 369 return -1 | |
| 370 } else if a && !b { | |
| 371 return 1 | |
| 372 } | |
| 373 return 0 | |
| 374 } | |
| 375 | |
| 376 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.In t64: | |
| 377 return func(av, bv reflect.Value) int { | |
| 378 a, b := av.Int(), bv.Int() | |
| 379 if a < b { | |
| 380 return -1 | |
| 381 } else if a > b { | |
| 382 return 1 | |
| 383 } | |
| 384 return 0 | |
| 385 } | |
| 386 | |
| 387 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, | |
| 388 reflect.Uint64, reflect.Uintptr, reflect.UnsafePointer: | |
| 389 return func(av, bv reflect.Value) int { | |
| 390 a, b := av.Uint(), bv.Uint() | |
| 391 if a < b { | |
| 392 return -1 | |
| 393 } else if a > b { | |
| 394 return 1 | |
| 395 } | |
| 396 return 0 | |
| 397 } | |
| 398 | |
| 399 case reflect.Float32, reflect.Float64: | |
| 400 return func(av, bv reflect.Value) int { | |
| 401 a, b := av.Float(), bv.Float() | |
| 402 if a < b { | |
| 403 return -1 | |
| 404 } else if a > b { | |
| 405 return 1 | |
| 406 } | |
| 407 return 0 | |
| 408 } | |
| 409 | |
| 410 case reflect.Interface: | |
| 411 return func(av, bv reflect.Value) int { | |
| 412 a, b := av.InterfaceData(), bv.InterfaceData() | |
| 413 if a[0] < b[0] { | |
| 414 return -1 | |
| 415 } else if a[0] > b[0] { | |
| 416 return 1 | |
| 417 } | |
| 418 if a[1] < b[1] { | |
| 419 return -1 | |
| 420 } else if a[1] > b[1] { | |
| 421 return 1 | |
| 422 } | |
| 423 return 0 | |
| 424 } | |
| 425 | |
| 426 case reflect.Complex64, reflect.Complex128: | |
| 427 return func(av, bv reflect.Value) int { | |
| 428 a, b := av.Complex(), bv.Complex() | |
| 429 if real(a) < real(b) { | |
| 430 return -1 | |
| 431 } else if real(a) > real(b) { | |
| 432 return 1 | |
| 433 } | |
| 434 if imag(a) < imag(b) { | |
| 435 return -1 | |
| 436 } else if imag(a) > imag(b) { | |
| 437 return 1 | |
| 438 } | |
| 439 return 0 | |
| 440 } | |
| 441 | |
| 442 case reflect.Ptr, reflect.Chan: | |
| 443 return func(av, bv reflect.Value) int { | |
| 444 a, b := av.Pointer(), bv.Pointer() | |
| 445 if a < b { | |
| 446 return -1 | |
| 447 } else if a > b { | |
| 448 return 1 | |
| 449 } | |
| 450 return 0 | |
| 451 } | |
| 452 | |
| 453 case reflect.Struct: | |
| 454 cmpLst := make([]cmpFn, t.NumField()) | |
| 455 for i := range cmpLst { | |
| 456 cmpLst[i] = cmpForType(t.Field(i).Type) | |
| 457 } | |
| 458 return func(a, b reflect.Value) int { | |
| 459 for i, cmp := range cmpLst { | |
| 460 rslt := cmp(a.Field(i), b.Field(i)) | |
|
dnj
2016/02/19 19:31:10
nit: if rstl := cmp(); rstl != 0 { ... }
iannucci
2016/02/19 21:18:28
Done.
| |
| 461 if rslt != 0 { | |
| 462 return rslt | |
| 463 } | |
| 464 } | |
| 465 return 0 | |
| 466 } | |
| 467 } | |
| 468 | |
| 469 return nil | |
| 470 } | |
| 471 | |
| 359 func tryAndSortMapKeys(mt reflect.Type, k []reflect.Value) { | 472 func tryAndSortMapKeys(mt reflect.Type, k []reflect.Value) { |
| 360 » // Try our stock sortable values. | 473 » if cmp := cmpForType(mt.Key()); cmp != nil { |
| 361 » switch mt.Key().Kind() { | 474 » » sort.Sort(sortableValueSlice{cmp, k}) |
| 362 » case reflect.String, reflect.Int: | |
| 363 » » vs := &sortableValueSlice{ | |
| 364 » » » kind: mt.Key().Kind(), | |
| 365 » » » elements: k, | |
| 366 » » } | |
| 367 » » sort.Sort(vs) | |
| 368 } | 475 } |
| 369 } | 476 } |
| OLD | NEW |