text: ////////////////////////////////////////////////////////////////////////////////
  //  Copyright (c) 2007-2018 Hartmut Kaiser
  //  Copyright (c) 2011 Bryce Adelstein-Lelbach
  //
  //  SPDX-License-Identifier: BSL-1.0
  //  Distributed under the Boost Software License, Version 1.0. (See accompanying
  //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  ////////////////////////////////////////////////////////////////////////////////
  
  /// \file manage_counter_type.hpp
  
  #pragma once
  
  #include <hpx/config.hpp>
  #include <hpx/functional/function.hpp>
  #include <hpx/modules/errors.hpp>
  #include <hpx/performance_counters/counters_fwd.hpp>
  
  #include <cstddef>
  #include <cstdint>
  #include <string>
  #include <vector>
  
  namespace hpx { namespace performance_counters {
  
      /// \brief Install a new generic performance counter type in a way, which
      ///        will uninstall it automatically during shutdown.
      ///
      /// The function \a install_counter_type will register a new generic
      /// counter type based on the provided function. The counter
      /// type will be automatically unregistered during system shutdown. Any
      /// consumer querying any instance of this this counter type will cause the
      /// provided function to be called and the returned value to be exposed as
      /// the counter value.
      ///
      /// The counter type is registered such that there can be one counter
      /// instance per locality. The expected naming scheme for the counter
      /// instances is: \c '/objectname{locality#<*>/total}/countername' where
      /// '<*>' is a zero based integer identifying the locality the counter
      /// is created on.
      ///
      /// \param name   [in] The global virtual name of the counter type. This
      ///               name is expected to have the format /objectname/countername.
      /// \param counter_value [in] The function to call whenever the counter
      ///               value is requested by a consumer.
      /// \param helptext [in, optional] A longer descriptive text shown to the
      ///               user to explain the nature of the counters created from
      ///               this type.
      /// \param uom    [in] The unit of measure for the new performance counter
      ///               type.
      /// \param type   [in] Type for the new performance counter type.
      /// \param ec     [in,out] this represents the error status on exit,
      ///               if this is pre-initialized to \a hpx#throws
      ///               the function will throw on error instead.
      ///
      /// \note As long as \a ec is not pre-initialized to \a hpx::throws this
      ///       function doesn't throw but returns the result code using the
      ///       parameter \a ec. Otherwise it throws an instance of hpx::exception.
      ///
      /// \returns      If successful, this function returns \a status_valid_data,
      ///               otherwise it will either throw an exception or return an
      ///               error_code from the enum \a counter_status (also, see
      ///               note related to parameter \a ec).
      ///
      /// \note The counter type registry is a locality based service. You will
      ///       have to register each counter type on every locality where a
      ///       corresponding performance counter will be created.
      HPX_EXPORT counter_status install_counter_type(std::string const& name,
          hpx::util::function_nonser<std::int64_t(bool)> const& counter_value,
          std::string const& helptext = "", std::string const& uom = "",
          counter_type type = counter_raw, error_code& ec = throws);
  
      /// Install a new generic performance counter type returning an
      /// array of values in a way, that will uninstall it automatically during
      /// shutdown.
      ///
      /// The function \a install_counter_type will register a new generic
      /// counter type that returns an array of values based on the provided
      /// function. The counter
      /// type will be automatically unregistered during system shutdown. Any
      /// consumer querying any instance of this this counter type will cause the
      /// provided function to be called and the returned array value to be
      /// exposed as the counter value.
      ///
      /// The counter type is registered such that there can be one counter
      /// instance per locality. The expected naming scheme for the counter
      /// instances is: \c '/objectname{locality#<*>/total}/countername' where
      /// '<*>' is a zero based integer identifying the locality the counter
      /// is created on.
      ///
      /// \param name   [in] The global virtual name of the counter type. This
      ///               name is expected to have the format /objectname/countername.
      /// \param counter_value [in] The function to call whenever the counter
      ///               value (array of values) is requested by a consumer.
      /// \param helptext [in, optional] A longer descriptive text shown to the
      ///               user to explain the nature of the counters created from
      ///               this type.
      /// \param uom    [in] The unit of measure for the new performance counter
      ///               type.
      /// \param ec     [in,out] this represents the error status on exit,
      ///               if this is pre-initialized to \a hpx#throws
      ///               the function will throw on error instead.
      ///
      /// \note As long as \a ec is not pre-initialized to \a hpx::throws this
      ///       function doesn't throw but returns the result code using the
      ///       parameter \a ec. Otherwise it throws an instance of hpx::exception.
      ///
      /// \returns      If successful, this function returns \a status_valid_data,
      ///               otherwise it will either throw an exception or return an
      ///               error_code from the enum \a counter_status (also, see
      ///               note related to parameter \a ec).
      ///
      /// \note The counter type registry is a locality based service. You will
      ///       have to register each counter type on every locality where a
      ///       corresponding performance counter will be created.
      HPX_EXPORT counter_status install_counter_type(std::string const& name,
          hpx::util::function_nonser<std::vector<std::int64_t>(bool)> const&
              counter_value,
          std::string const& helptext = "", std::string const& uom = "",
          error_code& ec = throws);
  
      /// \brief Install a new performance counter type in a way, which will
      ///        uninstall it automatically during shutdown.
      ///
      /// The function \a install_counter_type will register a new counter type
      /// based on the provided \a counter_type_info. The counter type will be
      /// automatically unregistered during system shutdown.
      ///
      /// \param name   [in] The global virtual name of the counter type. This
      ///               name is expected to have the format /objectname/countername.
      /// \param type   [in] The type of the counters of  this counter_type.
      /// \param ec     [in,out] this represents the error status on exit,
      ///               if this is pre-initialized to \a hpx#throws
      ///               the function will throw on error instead.
      ///
      /// \returns      If successful, this function returns \a status_valid_data,
      ///               otherwise it will either throw an exception or return an
      ///               error_code from the enum \a counter_status (also, see
      ///               note related to parameter \a ec).
      ///
      /// \note The counter type registry is a locality based service. You will
      ///       have to register each counter type on every locality where a
      ///       corresponding performance counter will be created.
      ///
      /// \note As long as \a ec is not pre-initialized to \a hpx#throws this
      ///       function doesn't throw but returns the result code using the
      ///       parameter \a ec. Otherwise it throws an instance of hpx#exception.
      HPX_EXPORT void install_counter_type(
          std::string const& name, counter_type type, error_code& ec = throws);
  
      /// \brief Install a new performance counter type in a way, which will
      ///        uninstall it automatically during shutdown.
      ///
      /// The function \a install_counter_type will register a new counter type
      /// based on the provided \a counter_type_info. The counter type will be
      /// automatically unregistered during system shutdown.
      ///
      /// \param name   [in] The global virtual name of the counter type. This
      ///               name is expected to have the format /objectname/countername.
      /// \param type   [in] The type of the counters of  this counter_type.
      /// \param helptext [in] A longer descriptive  text shown to the user to
      ///               explain the nature of the counters created from this
      ///               type.
      /// \param uom    [in] The unit of measure for the new performance counter
      ///               type.
      /// \param version [in] The version of the counter type. This is currently
      ///               expected to be set to HPX_PERFORMANCE_COUNTER_V1.
      /// \param ec     [in,out] this represents the error status on exit,
      ///               if this is pre-initialized to \a hpx#throws
      ///               the function will throw on error instead.
      ///
      /// \returns      If successful, this function returns \a status_valid_data,
      ///               otherwise it will either throw an exception or return an
      ///               error_code from the enum \a counter_status (also, see
      ///               note related to parameter \a ec).
      ///
      /// \note The counter type registry is a locality based service. You will
      ///       have to register each counter type on every locality where a
      ///       corresponding performance counter will be created.
      ///
      /// \note As long as \a ec is not pre-initialized to \a hpx#throws this
      ///       function doesn't throw but returns the result code using the
      ///       parameter \a ec. Otherwise it throws an instance of hpx#exception.
      HPX_EXPORT counter_status install_counter_type(std::string const& name,
          counter_type type, std::string const& helptext,
          std::string const& uom = "",
          std::uint32_t version = HPX_PERFORMANCE_COUNTER_V1,
          error_code& ec = throws);
  
      /// \brief Install a new generic performance counter type in a way, which
      ///        will uninstall it automatically during shutdown.
      ///
      /// The function \a install_counter_type will register a new generic
      /// counter type based on the provided \a counter_type_info. The counter
      /// type will be automatically unregistered during system shutdown.
      ///
      /// \param name   [in] The global virtual name of the counter type. This
      ///               name is expected to have the format /objectname/countername.
      /// \param type   [in] The type of the counters of  this counter_type.
      /// \param helptext [in] A longer descriptive  text shown to the user to
      ///               explain the nature of the counters created from this
      ///               type.
      /// \param version [in] The version of the counter type. This is currently
      ///               expected to be set to HPX_PERFORMANCE_COUNTER_V1.
      /// \param create_counter [in] The function which will be called to create
      ///               a new instance of this counter type.
      /// \param discover_counters [in] The function will be called to discover
      ///               counter instances which can be created.
      /// \param uom    [in] The unit of measure of the counter type (default: "")
      /// \param ec     [in,out] this represents the error status on exit,
      ///               if this is pre-initialized to \a hpx#throws
      ///               the function will throw on error instead.
      ///
      /// \note As long as \a ec is not pre-initialized to \a hpx#throws this
      ///       function doesn't throw but returns the result code using the
      ///       parameter \a ec. Otherwise it throws an instance of hpx#exception.
      ///
      /// \returns      If successful, this function returns \a status_valid_data,
      ///               otherwise it will either throw an exception or return an
      ///               error_code from the enum \a counter_status (also, see
      ///               note related to parameter \a ec).
      ///
      /// \note The counter type registry is a locality based service. You will
      ///       have to register each counter type on every locality where a
      ///       corresponding performance counter will be created.
      HPX_EXPORT counter_status install_counter_type(std::string const& name,
          counter_type type, std::string const& helptext,
          create_counter_func const& create_counter,
          discover_counters_func const& discover_counters,
          std::uint32_t version = HPX_PERFORMANCE_COUNTER_V1,
          std::string const& uom = "", error_code& ec = throws);
  
      /// \cond NOINTERNAL
  
      /// A small data structure holding all data needed to install a counter type
      struct generic_counter_type_data
      {
          std::string name_;         ///< Name of the counter type
          counter_type type_;        ///< Type of the counter instances of this
                                     ///< counter type
          std::string helptext_;     ///< Longer descriptive text explaining the
                                     ///< counter type
          std::uint32_t version_;    ///< Version of this counter type definition
                                     ///< (default: HPX_PERFORMANCE_COUNTER_V1)
          create_counter_func create_counter_;
          ///< Function used to create a counter instance of this type.
          discover_counters_func discover_counters_;
          ///< Function used to discover all supported counter instances of
          ///< this type.
          std::string unit_of_measure_;
          ///< The textual representation of the unit of measure for counter
          ///< instances of this type. Use ISO unit names.
      };
  
      /// Install several new performance counter types in a way, which will
      /// uninstall them automatically during shutdown.
      HPX_EXPORT void install_counter_types(generic_counter_type_data const* data,
          std::size_t count, error_code& ec = throws);
  
      /// \endcond
  }}    // namespace hpx::performance_counters
  