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

// Copyright (C) 2020-2025 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

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

#include <bits/requires_hosted.h> // concurrency

#define __glibcxx_want_semaphore
#include <bits/version.h>

#ifdef __cpp_lib_semaphore // C++ >= 20 && hosted && atomic_wait
#include <bits/semaphore_base.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

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

      _Semaphore_impl<__least_max_value> _M_sem;

    public:
      constexpr explicit
      counting_semaphore(ptrdiff_t __desired) noexcept
      : _M_sem(__desired)
      { __glibcxx_assert(__desired >= 0 && __desired <= max()); }

      ~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
      {
	[[maybe_unused]] ptrdiff_t __old = _M_sem._M_release(__update);
	__glibcxx_assert(__update >= 0 && __update <= max() - __old);
      }

      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); }
    };

  /** @brief A binary semaphore
   *
   * @since C++20
   */
  using binary_semaphore = std::counting_semaphore<1>;

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // __cpp_lib_semaphore
#endif // _GLIBCXX_SEMAPHORE
