value_119.go raw

   1  // Copyright 2022 The Go Authors. All rights reserved.
   2  // Use of this source code is governed by a BSD-style
   3  // license that can be found in the LICENSE file.
   4  
   5  //go:build go1.19 && !go1.20
   6  
   7  package slog
   8  
   9  import (
  10  	"reflect"
  11  	"unsafe"
  12  )
  13  
  14  type (
  15  	stringptr unsafe.Pointer // used in Value.any when the Value is a string
  16  	groupptr  unsafe.Pointer // used in Value.any when the Value is a []Attr
  17  )
  18  
  19  // StringValue returns a new Value for a string.
  20  func StringValue(value string) Value {
  21  	hdr := (*reflect.StringHeader)(unsafe.Pointer(&value))
  22  	return Value{num: uint64(hdr.Len), any: stringptr(hdr.Data)}
  23  }
  24  
  25  func (v Value) str() string {
  26  	var s string
  27  	hdr := (*reflect.StringHeader)(unsafe.Pointer(&s))
  28  	hdr.Data = uintptr(v.any.(stringptr))
  29  	hdr.Len = int(v.num)
  30  	return s
  31  }
  32  
  33  // String returns Value's value as a string, formatted like fmt.Sprint. Unlike
  34  // the methods Int64, Float64, and so on, which panic if v is of the
  35  // wrong kind, String never panics.
  36  func (v Value) String() string {
  37  	if sp, ok := v.any.(stringptr); ok {
  38  		// Inlining this code makes a huge difference.
  39  		var s string
  40  		hdr := (*reflect.StringHeader)(unsafe.Pointer(&s))
  41  		hdr.Data = uintptr(sp)
  42  		hdr.Len = int(v.num)
  43  		return s
  44  	}
  45  	return string(v.append(nil))
  46  }
  47  
  48  // GroupValue returns a new Value for a list of Attrs.
  49  // The caller must not subsequently mutate the argument slice.
  50  func GroupValue(as ...Attr) Value {
  51  	hdr := (*reflect.SliceHeader)(unsafe.Pointer(&as))
  52  	return Value{num: uint64(hdr.Len), any: groupptr(hdr.Data)}
  53  }
  54