package nstd

import (
	
)

// Methods of *Mutex return a *Mutex result, so that
// these methods may be called in a chain.
// It is just a simpler wrapper of the [sync.Mutex].
// The main purpose of this type is to support
// the following use case:
//
//	var aMutex nstd.Mutex
//
//	func foo() {
//		defer aMutex.Lock().Unlock()
//		... // do something
//	}
type Mutex struct {
	mu sync.Mutex
}

// Lock return m, so that the methods of m can be called in chain.
func ( *Mutex) () *Mutex {
	.mu.Lock()
	return 
}

// Unlock return m, so that the methods of m can be called in chain.
func ( *Mutex) () *Mutex {
	.mu.Unlock()
	return 
}

// Do guards the execution of a function in Lock() and Unlock()
//
// See: https://github.com/golang/go/issues/63941
func ( *Mutex) ( func()) {
	defer .Lock().Unlock()
	()
}

// WaitGroup extends sync.WaitGroup.
// Each WaitGroup maintains an internal count which initial value is zero.
type WaitGroup struct {
	wg sync.WaitGroup
}

// GoN starts several concurrent tasks and increases the internal count by len(fs).
// The internal count will be descreased by one when each of the task is done.
//
// See: https://github.com/golang/go/issues/18022
func ( *WaitGroup) ( ...func()) {
	for ,  := range  {
		if  == nil {
			Panicf("fs[%d] is nil", )
		}
	}
	.wg.Add(len())
	for ,  := range  {
		 := 
		go func() {
			defer .wg.Done()
			()
		}()
	}
}

// GoN starts a task n times concurrently and increases the internal count by n.
// The internal count will be descreased by one when each of the task instances is done.
func ( *WaitGroup) ( int,  func()) {
	if  < 0 {
		panic("the count must not be negative")
	}
	if  == nil {
		panic("f is nil")
	}
	.wg.Add()
	for  := 0;  < ; ++ {
		go func() {
			defer .wg.Done()
			()
		}()
	}
}

// Wait blocks until the internal counter is zero.
func ( *WaitGroup) () {
	.wg.Wait()
}

// WaitChannel returns a channel which reads will block until the internal counter is zero.
func ( *WaitGroup) () <-chan struct{} {
	var  = make(chan struct{})

	go func() {
		.wg.Wait()
		close()
	}()

	return 
}