3.3.9.8.1.1. Program Listing for File fftw.hΒΆ

#ifndef SIRIUS_FFTW_FFTW_H_
#define SIRIUS_FFTW_FFTW_H_

#include <map>
#include <memory>
#include <type_traits>

#include "sirius/fftw/types.h"
#include "sirius/image.h"
#include "sirius/types.h"

#include "sirius/utils/lru_cache.h"

namespace sirius {
namespace fftw {

namespace detail {

struct PlanDeleter {
    void operator()(::fftw_plan plan);
};
}  // namespace detail

using PlanUPtr =
      std::unique_ptr<std::remove_pointer_t<::fftw_plan>, detail::PlanDeleter>;
using PlanSPtr = std::shared_ptr<std::remove_pointer_t<::fftw_plan>>;

class Fftw {
  private:
    static constexpr int kCacheSize = 10;
    using PlanCache = utils::LRUCache<Size, PlanSPtr, kCacheSize>;

  public:
    static Fftw& Instance();

    PlanSPtr GetRealToComplexPlan(const Size& size, double* in,
                                  fftw_complex* out);
    PlanSPtr GetComplexToRealPlan(const Size& size, fftw_complex* in,
                                  double* out);

  private:
    Fftw() = default;

    // not copyable
    Fftw(const Fftw&) = delete;
    Fftw operator=(const Fftw&) = delete;
    // not moveable
    Fftw(Fftw&&) = delete;
    Fftw operator=(Fftw&&) = delete;

    PlanSPtr CreateC2RPlan(const Size& size, fftw_complex* in, double* out);
    PlanSPtr CreateR2CPlan(const Size& size, double* out, fftw_complex* in);

    // allow PlanDeleter operator() to access private DestroyPlan method
    friend void detail::PlanDeleter::operator()(::fftw_plan);
    void DestroyPlan(::fftw_plan plan);

  private:
    std::mutex plan_mutex_;

    PlanCache r2c_plans_;
    PlanCache c2r_plans_;
};

}  // namespace fftw
}  // namespace sirius

#endif  // SIRIUS_FFTW_FFTW_H_