github.com/gogf/gf@v1.16.9/container/gtype/bool.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  
     7  package gtype
     8  
     9  import (
    10  	"bytes"
    11  	"github.com/gogf/gf/util/gconv"
    12  	"sync/atomic"
    13  )
    14  
    15  // Bool is a struct for concurrent-safe operation for type bool.
    16  type Bool struct {
    17  	value int32
    18  }
    19  
    20  var (
    21  	bytesTrue  = []byte("true")
    22  	bytesFalse = []byte("false")
    23  )
    24  
    25  // NewBool creates and returns a concurrent-safe object for bool type,
    26  // with given initial value <value>.
    27  func NewBool(value ...bool) *Bool {
    28  	t := &Bool{}
    29  	if len(value) > 0 {
    30  		if value[0] {
    31  			t.value = 1
    32  		} else {
    33  			t.value = 0
    34  		}
    35  	}
    36  	return t
    37  }
    38  
    39  // Clone clones and returns a new concurrent-safe object for bool type.
    40  func (v *Bool) Clone() *Bool {
    41  	return NewBool(v.Val())
    42  }
    43  
    44  // Set atomically stores <value> into t.value and returns the previous value of t.value.
    45  func (v *Bool) Set(value bool) (old bool) {
    46  	if value {
    47  		old = atomic.SwapInt32(&v.value, 1) == 1
    48  	} else {
    49  		old = atomic.SwapInt32(&v.value, 0) == 1
    50  	}
    51  	return
    52  }
    53  
    54  // Val atomically loads and returns t.valueue.
    55  func (v *Bool) Val() bool {
    56  	return atomic.LoadInt32(&v.value) > 0
    57  }
    58  
    59  // Cas executes the compare-and-swap operation for value.
    60  func (v *Bool) Cas(old, new bool) (swapped bool) {
    61  	var oldInt32, newInt32 int32
    62  	if old {
    63  		oldInt32 = 1
    64  	}
    65  	if new {
    66  		newInt32 = 1
    67  	}
    68  	return atomic.CompareAndSwapInt32(&v.value, oldInt32, newInt32)
    69  }
    70  
    71  // String implements String interface for string printing.
    72  func (v *Bool) String() string {
    73  	if v.Val() {
    74  		return "true"
    75  	}
    76  	return "false"
    77  }
    78  
    79  // MarshalJSON implements the interface MarshalJSON for json.Marshal.
    80  func (v *Bool) MarshalJSON() ([]byte, error) {
    81  	if v.Val() {
    82  		return bytesTrue, nil
    83  	} else {
    84  		return bytesFalse, nil
    85  	}
    86  }
    87  
    88  // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
    89  func (v *Bool) UnmarshalJSON(b []byte) error {
    90  	v.Set(gconv.Bool(bytes.Trim(b, `"`)))
    91  	return nil
    92  }
    93  
    94  // UnmarshalValue is an interface implement which sets any type of value for <v>.
    95  func (v *Bool) UnmarshalValue(value interface{}) error {
    96  	v.Set(gconv.Bool(value))
    97  	return nil
    98  }