// ---------------------------------------------------------------------
//
// Copyright (C) 2019 by the SampleFlow authors.
//
// This file is part of the SampleFlow library.
//
// The deal.II library is free software; you can use it, redistribute
// it, and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// The full text of the license can be found in the file LICENSE.md at
// the top level directory of deal.II.
//
// ---------------------------------------------------------------------

#ifndef SAMPLEFLOW_CONSUMERS_COUNT_SAMPLES_H
#define SAMPLEFLOW_CONSUMERS_COUNT_SAMPLES_H

#include <sampleflow/consumer.h>
#include <mutex>


namespace SampleFlow
{
  namespace Consumers
  {
    /**
     * A Consumer class that simply counts how many samples it has received.
     *
     *
     * ### Threading model ###
     *
     * The implementation of this class is thread-safe, i.e., its
     * consume() member function can be called concurrently and from multiple
     * threads.
     *
     *
     * @tparam InputType The C++ type used for the samples $x_k$.
     */
    template <typename InputType>
    class CountSamples : public Consumer<InputType>
    {
      public:
        /**
         * The type of the information generated by this class, i.e., the type
         * of the object returned by get(). This is just the type used to store
         * the index of samples.
         */
        using value_type = types::sample_index;

        /**
         * Constructor.
         */
        CountSamples ();

        /**
         * Process one sample by just incrementing the sample counter.
         *
         * @param[in] sample The sample to process. Since this class does
         *   not care about the actual value of the sample, it simply
         *   ignores its value.
         * @param[in] aux_data Auxiliary data about this sample. The current
         *   class does not know what to do with any such data and consequently
         *   simply ignores it.
         */
        virtual
        void
        consume (InputType sample, AuxiliaryData aux_data) override;

        /**
         * A function that returns the number of samples received so far.
         *
         * @return The computed mean value.
         */
        value_type
        get () const;

      private:
        /**
         * A mutex used to lock access to all member variables when running
         * on multiple threads.
         */
        mutable std::mutex mutex;

        /**
         * The number of samples received so far.
         */
        types::sample_index n_samples;
    };



    template <typename InputType>
    CountSamples<InputType>::
    CountSamples ()
      :
      n_samples (0)
    {}



    template <typename InputType>
    void
    CountSamples<InputType>::
    consume (InputType /*sample*/, AuxiliaryData /*aux_data*/)
    {
      std::lock_guard<std::mutex> lock(mutex);

      ++n_samples;
    }



    template <typename InputType>
    typename CountSamples<InputType>::value_type
    CountSamples<InputType>::
    get () const
    {
      std::lock_guard<std::mutex> lock(mutex);

      return n_samples;
    }

  }
}

#endif

Add a consumer that just counts samples.
Add a consumer that just counts samples.
