github.com/mitghi/x@v0.0.0-20191206171256-71e86edf750d/atoms/boolean.go (about)

     1  /* MIT License
     2  * 
     3  * Copyright (c) 2018 Mike Taghavi <mitghi[at]gmail.com>
     4  * 
     5  * Permission is hereby granted, free of charge, to any person obtaining a copy
     6  * of this software and associated documentation files (the "Software"), to deal
     7  * in the Software without restriction, including without limitation the rights
     8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     9  * copies of the Software, and to permit persons to whom the Software is
    10  * furnished to do so, subject to the following conditions:
    11  * The above copyright notice and this permission notice shall be included in all
    12  * copies or substantial portions of the Software.
    13  * 
    14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    20  * SOFTWARE.
    21  */
    22  
    23  package atoms
    24  
    25  import (
    26  	"sync/atomic"
    27  )
    28  
    29  // Boolean is atomic type
    30  type Boolean uint32
    31  
    32  // NewBoolean allocates and initialize a new
    33  // atomic boolean and returns a pointer to it.
    34  func NewBoolean() *Boolean {
    35  	return new(Boolean)
    36  }
    37  
    38  // Set sets the state to `v`.
    39  func (b *Boolean) Set(v bool) {
    40  	atomic.StoreUint32((*uint32)(b), btoi(v))
    41  }
    42  
    43  // value is a internal receiver function
    44  // that returns the raw value.
    45  func (b *Boolean) value() uint32 {
    46  	return atomic.LoadUint32((*uint32)(b))
    47  }
    48  
    49  // Get returns the value.
    50  func (b *Boolean) Get() (value bool) {
    51  	return atomic.LoadUint32((*uint32)(b)) == 1
    52  }
    53  
    54  // Is compares whether the internal value
    55  // is equal to `v`.
    56  func (b *Boolean) Is(v bool) (ok bool) {
    57  	return atomic.LoadUint32((*uint32)(b)) == btoi(v)
    58  }
    59  
    60  // Flip reverses the internal value
    61  func (b *Boolean) Flip() (bool, bool) {
    62  	var (
    63  		curr uint32 = (*b).value()
    64  		n    uint32 = curr ^ 0x1
    65  	)
    66  	if atomic.CompareAndSwapUint32((*uint32)(b), curr, n) {
    67  		return itob(n), true
    68  	}
    69  
    70  	return false, false
    71  }
    72  
    73  // CAS performs atomic Compare-and-Swap
    74  // operation and returns the new value.
    75  func (b *Boolean) CAS(o, n bool) (ok bool) {
    76  	return atomic.CompareAndSwapUint32((*uint32)(b), btoi(o), btoi(n))
    77  }
    78  
    79  // btoi converts a `bool` to `uint32`.
    80  func btoi(b bool) uint32 {
    81  	if b {
    82  		return 1
    83  	}
    84  
    85  	return 0
    86  }
    87  
    88  // btoiR converts a `bool` to `uint32`
    89  // and returns the reverse value.
    90  func btoiR(b bool) uint32 {
    91  	if b {
    92  		return 0
    93  	}
    94  
    95  	return 1
    96  }
    97  
    98  // itob converts a `uint32` to
    99  // `boolean`.
   100  func itob(ui uint32) bool {
   101  	if ui == 1 {
   102  		return true
   103  	}
   104  
   105  	return false
   106  }