github.com/wangyougui/gf/v2@v2.6.5/container/gtype/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/wangyougui/gf.
     6  
     7  package gtype
     8  
     9  import (
    10  	"bytes"
    11  	"sync/atomic"
    12  
    13  	"github.com/wangyougui/gf/v2/util/gconv"
    14  )
    15  
    16  // Bool is a struct for concurrent-safe operation for type bool.
    17  type Bool struct {
    18  	value int32
    19  }
    20  
    21  var (
    22  	bytesTrue  = []byte("true")
    23  	bytesFalse = []byte("false")
    24  )
    25  
    26  // NewBool creates and returns a concurrent-safe object for bool type,
    27  // with given initial value `value`.
    28  func NewBool(value ...bool) *Bool {
    29  	t := &Bool{}
    30  	if len(value) > 0 {
    31  		if value[0] {
    32  			t.value = 1
    33  		} else {
    34  			t.value = 0
    35  		}
    36  	}
    37  	return t
    38  }
    39  
    40  // Clone clones and returns a new concurrent-safe object for bool type.
    41  func (v *Bool) Clone() *Bool {
    42  	return NewBool(v.Val())
    43  }
    44  
    45  // Set atomically stores `value` into t.value and returns the previous value of t.value.
    46  func (v *Bool) Set(value bool) (old bool) {
    47  	if value {
    48  		old = atomic.SwapInt32(&v.value, 1) == 1
    49  	} else {
    50  		old = atomic.SwapInt32(&v.value, 0) == 1
    51  	}
    52  	return
    53  }
    54  
    55  // Val atomically loads and returns t.value.
    56  func (v *Bool) Val() bool {
    57  	return atomic.LoadInt32(&v.value) > 0
    58  }
    59  
    60  // Cas executes the compare-and-swap operation for value.
    61  func (v *Bool) Cas(old, new bool) (swapped bool) {
    62  	var oldInt32, newInt32 int32
    63  	if old {
    64  		oldInt32 = 1
    65  	}
    66  	if new {
    67  		newInt32 = 1
    68  	}
    69  	return atomic.CompareAndSwapInt32(&v.value, oldInt32, newInt32)
    70  }
    71  
    72  // String implements String interface for string printing.
    73  func (v *Bool) String() string {
    74  	if v.Val() {
    75  		return "true"
    76  	}
    77  	return "false"
    78  }
    79  
    80  // MarshalJSON implements the interface MarshalJSON for json.Marshal.
    81  func (v Bool) MarshalJSON() ([]byte, error) {
    82  	if v.Val() {
    83  		return bytesTrue, nil
    84  	}
    85  	return bytesFalse, nil
    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  }
    99  
   100  // DeepCopy implements interface for deep copy of current type.
   101  func (v *Bool) DeepCopy() interface{} {
   102  	if v == nil {
   103  		return nil
   104  	}
   105  	return NewBool(v.Val())
   106  }