// <semaphore> -*- C++ -*-

// Copyright (C) 2020-2021 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file include/semaphore
 *  This is a Standard C++ Library header.
 */

#ifndef _GLIBCXX_SEMAPHORE
#define _GLIBCXX_SEMAPHORE 1

#pragma GCC system_header

#if __cplusplus > 201703L
#include <bits/semaphore_base.h>

#if __cpp_lib_atomic_wait || _GLIBCXX_HAVE_POSIX_SEMAPHORE
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

#define __cpp_lib_semaphore 201907L

  template<ptrdiff_t __least_max_value = __semaphore_impl::_S_max>
    class counting_semaphore
    {
      static_assert(__least_max_value >= 0);
      static_assert(__least_max_value <= __semaphore_impl::_S_max);

      __semaphore_impl _M_sem;

    public:
      explicit counting_semaphore(ptrdiff_t __desired) noexcept
	: _M_sem(__desired)
      { }

      ~counting_semaphore() = default;

      counting_semaphore(const counting_semaphore&) = delete;
      counting_semaphore& operator=(const counting_semaphore&) = delete;

      static constexpr ptrdiff_t
      max() noexcept
      { return __least_max_value; }

      void
      release(ptrdiff_t __update = 1) noexcept(noexcept(_M_sem._M_release(1)))
      { _M_sem._M_release(__update); }

      void
      acquire() noexcept(noexcept(_M_sem._M_acquire()))
      { _M_sem._M_acquire(); }

      bool
      try_acquire() noexcept(noexcept(_M_sem._M_try_acquire()))
      { return _M_sem._M_try_acquire(); }

      template<typename _Rep, typename _Period>
	bool
	try_acquire_for(const std::chrono::duration<_Rep, _Period>& __rtime)
	{ return _M_sem._M_try_acquire_for(__rtime); }

      template<typename _Clock, typename _Dur>
	bool
	try_acquire_until(const std::chrono::time_point<_Clock, _Dur>& __atime)
	{ return _M_sem._M_try_acquire_until(__atime); }
    };

  using binary_semaphore = std::counting_semaphore<1>;

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // cpp_lib_atomic_wait || _GLIBCXX_HAVE_POSIX_SEMAPHORE
#endif // C++20
#endif // _GLIBCXX_SEMAPHORE
