///
/// NitroSound-Swift-Cxx-Bridge.hpp
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © Marc Rousavy @ Margelo
///

#pragma once

// Forward declarations of C++ defined types
// Forward declaration of `AVEncoderAudioQualityIOSType` to properly resolve imports.
namespace margelo::nitro::sound { enum class AVEncoderAudioQualityIOSType; }
// Forward declaration of `AVEncodingOption` to properly resolve imports.
namespace margelo::nitro::sound { enum class AVEncodingOption; }
// Forward declaration of `AVLinearPCMBitDepthKeyIOSType` to properly resolve imports.
namespace margelo::nitro::sound { enum class AVLinearPCMBitDepthKeyIOSType; }
// Forward declaration of `AVModeIOSOption` to properly resolve imports.
namespace margelo::nitro::sound { enum class AVModeIOSOption; }
// Forward declaration of `AudioEncoderAndroidType` to properly resolve imports.
namespace margelo::nitro::sound { enum class AudioEncoderAndroidType; }
// Forward declaration of `AudioQualityType` to properly resolve imports.
namespace margelo::nitro::sound { enum class AudioQualityType; }
// Forward declaration of `AudioSet` to properly resolve imports.
namespace margelo::nitro::sound { struct AudioSet; }
// Forward declaration of `AudioSourceAndroidType` to properly resolve imports.
namespace margelo::nitro::sound { enum class AudioSourceAndroidType; }
// Forward declaration of `HybridSoundSpec` to properly resolve imports.
namespace margelo::nitro::sound { class HybridSoundSpec; }
// Forward declaration of `OutputFormatAndroidType` to properly resolve imports.
namespace margelo::nitro::sound { enum class OutputFormatAndroidType; }
// Forward declaration of `PlayBackType` to properly resolve imports.
namespace margelo::nitro::sound { struct PlayBackType; }
// Forward declaration of `PlaybackEndType` to properly resolve imports.
namespace margelo::nitro::sound { struct PlaybackEndType; }
// Forward declaration of `RecordBackType` to properly resolve imports.
namespace margelo::nitro::sound { struct RecordBackType; }

// Forward declarations of Swift defined types
// Forward declaration of `HybridSoundSpec_cxx` to properly resolve imports.
namespace NitroSound { class HybridSoundSpec_cxx; }

// Include C++ defined types
#include "AVEncoderAudioQualityIOSType.hpp"
#include "AVEncodingOption.hpp"
#include "AVLinearPCMBitDepthKeyIOSType.hpp"
#include "AVModeIOSOption.hpp"
#include "AudioEncoderAndroidType.hpp"
#include "AudioQualityType.hpp"
#include "AudioSet.hpp"
#include "AudioSourceAndroidType.hpp"
#include "HybridSoundSpec.hpp"
#include "OutputFormatAndroidType.hpp"
#include "PlayBackType.hpp"
#include "PlaybackEndType.hpp"
#include "RecordBackType.hpp"
#include <NitroModules/Promise.hpp>
#include <NitroModules/PromiseHolder.hpp>
#include <NitroModules/Result.hpp>
#include <exception>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <unordered_map>

/**
 * Contains specialized versions of C++ templated types so they can be accessed from Swift,
 * as well as helper functions to interact with those C++ types from Swift.
 */
namespace margelo::nitro::sound::bridge::swift {

  // pragma MARK: std::shared_ptr<Promise<std::string>>
  /**
   * Specialized version of `std::shared_ptr<Promise<std::string>>`.
   */
  using std__shared_ptr_Promise_std__string__ = std::shared_ptr<Promise<std::string>>;
  inline std::shared_ptr<Promise<std::string>> create_std__shared_ptr_Promise_std__string__() noexcept {
    return Promise<std::string>::create();
  }
  inline PromiseHolder<std::string> wrap_std__shared_ptr_Promise_std__string__(std::shared_ptr<Promise<std::string>> promise) noexcept {
    return PromiseHolder<std::string>(std::move(promise));
  }
  
  // pragma MARK: std::function<void(const std::string& /* result */)>
  /**
   * Specialized version of `std::function<void(const std::string&)>`.
   */
  using Func_void_std__string = std::function<void(const std::string& /* result */)>;
  /**
   * Wrapper class for a `std::function<void(const std::string& / * result * /)>`, this can be used from Swift.
   */
  class Func_void_std__string_Wrapper final {
  public:
    explicit Func_void_std__string_Wrapper(std::function<void(const std::string& /* result */)>&& func): _function(std::make_unique<std::function<void(const std::string& /* result */)>>(std::move(func))) {}
    inline void call(std::string result) const noexcept {
      _function->operator()(result);
    }
  private:
    std::unique_ptr<std::function<void(const std::string& /* result */)>> _function;
  } SWIFT_NONCOPYABLE;
  Func_void_std__string create_Func_void_std__string(void* NON_NULL swiftClosureWrapper) noexcept;
  inline Func_void_std__string_Wrapper wrap_Func_void_std__string(Func_void_std__string value) noexcept {
    return Func_void_std__string_Wrapper(std::move(value));
  }
  
  // pragma MARK: std::function<void(const std::exception_ptr& /* error */)>
  /**
   * Specialized version of `std::function<void(const std::exception_ptr&)>`.
   */
  using Func_void_std__exception_ptr = std::function<void(const std::exception_ptr& /* error */)>;
  /**
   * Wrapper class for a `std::function<void(const std::exception_ptr& / * error * /)>`, this can be used from Swift.
   */
  class Func_void_std__exception_ptr_Wrapper final {
  public:
    explicit Func_void_std__exception_ptr_Wrapper(std::function<void(const std::exception_ptr& /* error */)>&& func): _function(std::make_unique<std::function<void(const std::exception_ptr& /* error */)>>(std::move(func))) {}
    inline void call(std::exception_ptr error) const noexcept {
      _function->operator()(error);
    }
  private:
    std::unique_ptr<std::function<void(const std::exception_ptr& /* error */)>> _function;
  } SWIFT_NONCOPYABLE;
  Func_void_std__exception_ptr create_Func_void_std__exception_ptr(void* NON_NULL swiftClosureWrapper) noexcept;
  inline Func_void_std__exception_ptr_Wrapper wrap_Func_void_std__exception_ptr(Func_void_std__exception_ptr value) noexcept {
    return Func_void_std__exception_ptr_Wrapper(std::move(value));
  }
  
  // pragma MARK: std::optional<std::string>
  /**
   * Specialized version of `std::optional<std::string>`.
   */
  using std__optional_std__string_ = std::optional<std::string>;
  inline std::optional<std::string> create_std__optional_std__string_(const std::string& value) noexcept {
    return std::optional<std::string>(value);
  }
  inline bool has_value_std__optional_std__string_(const std::optional<std::string>& optional) noexcept {
    return optional.has_value();
  }
  inline std::string get_std__optional_std__string_(const std::optional<std::string>& optional) noexcept {
    return optional.value();
  }
  
  // pragma MARK: std::optional<AVEncoderAudioQualityIOSType>
  /**
   * Specialized version of `std::optional<AVEncoderAudioQualityIOSType>`.
   */
  using std__optional_AVEncoderAudioQualityIOSType_ = std::optional<AVEncoderAudioQualityIOSType>;
  inline std::optional<AVEncoderAudioQualityIOSType> create_std__optional_AVEncoderAudioQualityIOSType_(const AVEncoderAudioQualityIOSType& value) noexcept {
    return std::optional<AVEncoderAudioQualityIOSType>(value);
  }
  inline bool has_value_std__optional_AVEncoderAudioQualityIOSType_(const std::optional<AVEncoderAudioQualityIOSType>& optional) noexcept {
    return optional.has_value();
  }
  inline AVEncoderAudioQualityIOSType get_std__optional_AVEncoderAudioQualityIOSType_(const std::optional<AVEncoderAudioQualityIOSType>& optional) noexcept {
    return optional.value();
  }
  
  // pragma MARK: std::optional<AVModeIOSOption>
  /**
   * Specialized version of `std::optional<AVModeIOSOption>`.
   */
  using std__optional_AVModeIOSOption_ = std::optional<AVModeIOSOption>;
  inline std::optional<AVModeIOSOption> create_std__optional_AVModeIOSOption_(const AVModeIOSOption& value) noexcept {
    return std::optional<AVModeIOSOption>(value);
  }
  inline bool has_value_std__optional_AVModeIOSOption_(const std::optional<AVModeIOSOption>& optional) noexcept {
    return optional.has_value();
  }
  inline AVModeIOSOption get_std__optional_AVModeIOSOption_(const std::optional<AVModeIOSOption>& optional) noexcept {
    return optional.value();
  }
  
  // pragma MARK: std::optional<AVEncodingOption>
  /**
   * Specialized version of `std::optional<AVEncodingOption>`.
   */
  using std__optional_AVEncodingOption_ = std::optional<AVEncodingOption>;
  inline std::optional<AVEncodingOption> create_std__optional_AVEncodingOption_(const AVEncodingOption& value) noexcept {
    return std::optional<AVEncodingOption>(value);
  }
  inline bool has_value_std__optional_AVEncodingOption_(const std::optional<AVEncodingOption>& optional) noexcept {
    return optional.has_value();
  }
  inline AVEncodingOption get_std__optional_AVEncodingOption_(const std::optional<AVEncodingOption>& optional) noexcept {
    return optional.value();
  }
  
  // pragma MARK: std::optional<double>
  /**
   * Specialized version of `std::optional<double>`.
   */
  using std__optional_double_ = std::optional<double>;
  inline std::optional<double> create_std__optional_double_(const double& value) noexcept {
    return std::optional<double>(value);
  }
  inline bool has_value_std__optional_double_(const std::optional<double>& optional) noexcept {
    return optional.has_value();
  }
  inline double get_std__optional_double_(const std::optional<double>& optional) noexcept {
    return optional.value();
  }
  
  // pragma MARK: std::optional<AVLinearPCMBitDepthKeyIOSType>
  /**
   * Specialized version of `std::optional<AVLinearPCMBitDepthKeyIOSType>`.
   */
  using std__optional_AVLinearPCMBitDepthKeyIOSType_ = std::optional<AVLinearPCMBitDepthKeyIOSType>;
  inline std::optional<AVLinearPCMBitDepthKeyIOSType> create_std__optional_AVLinearPCMBitDepthKeyIOSType_(const AVLinearPCMBitDepthKeyIOSType& value) noexcept {
    return std::optional<AVLinearPCMBitDepthKeyIOSType>(value);
  }
  inline bool has_value_std__optional_AVLinearPCMBitDepthKeyIOSType_(const std::optional<AVLinearPCMBitDepthKeyIOSType>& optional) noexcept {
    return optional.has_value();
  }
  inline AVLinearPCMBitDepthKeyIOSType get_std__optional_AVLinearPCMBitDepthKeyIOSType_(const std::optional<AVLinearPCMBitDepthKeyIOSType>& optional) noexcept {
    return optional.value();
  }
  
  // pragma MARK: std::optional<bool>
  /**
   * Specialized version of `std::optional<bool>`.
   */
  using std__optional_bool_ = std::optional<bool>;
  inline std::optional<bool> create_std__optional_bool_(const bool& value) noexcept {
    return std::optional<bool>(value);
  }
  inline bool has_value_std__optional_bool_(const std::optional<bool>& optional) noexcept {
    return optional.has_value();
  }
  inline bool get_std__optional_bool_(const std::optional<bool>& optional) noexcept {
    return optional.value();
  }
  
  // pragma MARK: std::optional<AudioSourceAndroidType>
  /**
   * Specialized version of `std::optional<AudioSourceAndroidType>`.
   */
  using std__optional_AudioSourceAndroidType_ = std::optional<AudioSourceAndroidType>;
  inline std::optional<AudioSourceAndroidType> create_std__optional_AudioSourceAndroidType_(const AudioSourceAndroidType& value) noexcept {
    return std::optional<AudioSourceAndroidType>(value);
  }
  inline bool has_value_std__optional_AudioSourceAndroidType_(const std::optional<AudioSourceAndroidType>& optional) noexcept {
    return optional.has_value();
  }
  inline AudioSourceAndroidType get_std__optional_AudioSourceAndroidType_(const std::optional<AudioSourceAndroidType>& optional) noexcept {
    return optional.value();
  }
  
  // pragma MARK: std::optional<OutputFormatAndroidType>
  /**
   * Specialized version of `std::optional<OutputFormatAndroidType>`.
   */
  using std__optional_OutputFormatAndroidType_ = std::optional<OutputFormatAndroidType>;
  inline std::optional<OutputFormatAndroidType> create_std__optional_OutputFormatAndroidType_(const OutputFormatAndroidType& value) noexcept {
    return std::optional<OutputFormatAndroidType>(value);
  }
  inline bool has_value_std__optional_OutputFormatAndroidType_(const std::optional<OutputFormatAndroidType>& optional) noexcept {
    return optional.has_value();
  }
  inline OutputFormatAndroidType get_std__optional_OutputFormatAndroidType_(const std::optional<OutputFormatAndroidType>& optional) noexcept {
    return optional.value();
  }
  
  // pragma MARK: std::optional<AudioEncoderAndroidType>
  /**
   * Specialized version of `std::optional<AudioEncoderAndroidType>`.
   */
  using std__optional_AudioEncoderAndroidType_ = std::optional<AudioEncoderAndroidType>;
  inline std::optional<AudioEncoderAndroidType> create_std__optional_AudioEncoderAndroidType_(const AudioEncoderAndroidType& value) noexcept {
    return std::optional<AudioEncoderAndroidType>(value);
  }
  inline bool has_value_std__optional_AudioEncoderAndroidType_(const std::optional<AudioEncoderAndroidType>& optional) noexcept {
    return optional.has_value();
  }
  inline AudioEncoderAndroidType get_std__optional_AudioEncoderAndroidType_(const std::optional<AudioEncoderAndroidType>& optional) noexcept {
    return optional.value();
  }
  
  // pragma MARK: std::optional<AudioQualityType>
  /**
   * Specialized version of `std::optional<AudioQualityType>`.
   */
  using std__optional_AudioQualityType_ = std::optional<AudioQualityType>;
  inline std::optional<AudioQualityType> create_std__optional_AudioQualityType_(const AudioQualityType& value) noexcept {
    return std::optional<AudioQualityType>(value);
  }
  inline bool has_value_std__optional_AudioQualityType_(const std::optional<AudioQualityType>& optional) noexcept {
    return optional.has_value();
  }
  inline AudioQualityType get_std__optional_AudioQualityType_(const std::optional<AudioQualityType>& optional) noexcept {
    return optional.value();
  }
  
  // pragma MARK: std::optional<AudioSet>
  /**
   * Specialized version of `std::optional<AudioSet>`.
   */
  using std__optional_AudioSet_ = std::optional<AudioSet>;
  inline std::optional<AudioSet> create_std__optional_AudioSet_(const AudioSet& value) noexcept {
    return std::optional<AudioSet>(value);
  }
  inline bool has_value_std__optional_AudioSet_(const std::optional<AudioSet>& optional) noexcept {
    return optional.has_value();
  }
  inline AudioSet get_std__optional_AudioSet_(const std::optional<AudioSet>& optional) noexcept {
    return optional.value();
  }
  
  // pragma MARK: std::unordered_map<std::string, std::string>
  /**
   * Specialized version of `std::unordered_map<std::string, std::string>`.
   */
  using std__unordered_map_std__string__std__string_ = std::unordered_map<std::string, std::string>;
  inline std::unordered_map<std::string, std::string> create_std__unordered_map_std__string__std__string_(size_t size) noexcept {
    std::unordered_map<std::string, std::string> map;
    map.reserve(size);
    return map;
  }
  inline std::vector<std::string> get_std__unordered_map_std__string__std__string__keys(const std__unordered_map_std__string__std__string_& map) noexcept {
    std::vector<std::string> keys;
    keys.reserve(map.size());
    for (const auto& entry : map) {
      keys.push_back(entry.first);
    }
    return keys;
  }
  inline std::string get_std__unordered_map_std__string__std__string__value(const std__unordered_map_std__string__std__string_& map, const std::string& key) noexcept {
    return map.find(key)->second;
  }
  inline void emplace_std__unordered_map_std__string__std__string_(std__unordered_map_std__string__std__string_& map, const std::string& key, const std::string& value) noexcept {
    map.emplace(key, value);
  }
  
  // pragma MARK: std::optional<std::unordered_map<std::string, std::string>>
  /**
   * Specialized version of `std::optional<std::unordered_map<std::string, std::string>>`.
   */
  using std__optional_std__unordered_map_std__string__std__string__ = std::optional<std::unordered_map<std::string, std::string>>;
  inline std::optional<std::unordered_map<std::string, std::string>> create_std__optional_std__unordered_map_std__string__std__string__(const std::unordered_map<std::string, std::string>& value) noexcept {
    return std::optional<std::unordered_map<std::string, std::string>>(value);
  }
  inline bool has_value_std__optional_std__unordered_map_std__string__std__string__(const std::optional<std::unordered_map<std::string, std::string>>& optional) noexcept {
    return optional.has_value();
  }
  inline std::unordered_map<std::string, std::string> get_std__optional_std__unordered_map_std__string__std__string__(const std::optional<std::unordered_map<std::string, std::string>>& optional) noexcept {
    return optional.value();
  }
  
  // pragma MARK: std::function<void(const RecordBackType& /* recordingMeta */)>
  /**
   * Specialized version of `std::function<void(const RecordBackType&)>`.
   */
  using Func_void_RecordBackType = std::function<void(const RecordBackType& /* recordingMeta */)>;
  /**
   * Wrapper class for a `std::function<void(const RecordBackType& / * recordingMeta * /)>`, this can be used from Swift.
   */
  class Func_void_RecordBackType_Wrapper final {
  public:
    explicit Func_void_RecordBackType_Wrapper(std::function<void(const RecordBackType& /* recordingMeta */)>&& func): _function(std::make_unique<std::function<void(const RecordBackType& /* recordingMeta */)>>(std::move(func))) {}
    inline void call(RecordBackType recordingMeta) const noexcept {
      _function->operator()(recordingMeta);
    }
  private:
    std::unique_ptr<std::function<void(const RecordBackType& /* recordingMeta */)>> _function;
  } SWIFT_NONCOPYABLE;
  Func_void_RecordBackType create_Func_void_RecordBackType(void* NON_NULL swiftClosureWrapper) noexcept;
  inline Func_void_RecordBackType_Wrapper wrap_Func_void_RecordBackType(Func_void_RecordBackType value) noexcept {
    return Func_void_RecordBackType_Wrapper(std::move(value));
  }
  
  // pragma MARK: std::function<void(const PlayBackType& /* playbackMeta */)>
  /**
   * Specialized version of `std::function<void(const PlayBackType&)>`.
   */
  using Func_void_PlayBackType = std::function<void(const PlayBackType& /* playbackMeta */)>;
  /**
   * Wrapper class for a `std::function<void(const PlayBackType& / * playbackMeta * /)>`, this can be used from Swift.
   */
  class Func_void_PlayBackType_Wrapper final {
  public:
    explicit Func_void_PlayBackType_Wrapper(std::function<void(const PlayBackType& /* playbackMeta */)>&& func): _function(std::make_unique<std::function<void(const PlayBackType& /* playbackMeta */)>>(std::move(func))) {}
    inline void call(PlayBackType playbackMeta) const noexcept {
      _function->operator()(playbackMeta);
    }
  private:
    std::unique_ptr<std::function<void(const PlayBackType& /* playbackMeta */)>> _function;
  } SWIFT_NONCOPYABLE;
  Func_void_PlayBackType create_Func_void_PlayBackType(void* NON_NULL swiftClosureWrapper) noexcept;
  inline Func_void_PlayBackType_Wrapper wrap_Func_void_PlayBackType(Func_void_PlayBackType value) noexcept {
    return Func_void_PlayBackType_Wrapper(std::move(value));
  }
  
  // pragma MARK: std::function<void(const PlaybackEndType& /* playbackEndMeta */)>
  /**
   * Specialized version of `std::function<void(const PlaybackEndType&)>`.
   */
  using Func_void_PlaybackEndType = std::function<void(const PlaybackEndType& /* playbackEndMeta */)>;
  /**
   * Wrapper class for a `std::function<void(const PlaybackEndType& / * playbackEndMeta * /)>`, this can be used from Swift.
   */
  class Func_void_PlaybackEndType_Wrapper final {
  public:
    explicit Func_void_PlaybackEndType_Wrapper(std::function<void(const PlaybackEndType& /* playbackEndMeta */)>&& func): _function(std::make_unique<std::function<void(const PlaybackEndType& /* playbackEndMeta */)>>(std::move(func))) {}
    inline void call(PlaybackEndType playbackEndMeta) const noexcept {
      _function->operator()(playbackEndMeta);
    }
  private:
    std::unique_ptr<std::function<void(const PlaybackEndType& /* playbackEndMeta */)>> _function;
  } SWIFT_NONCOPYABLE;
  Func_void_PlaybackEndType create_Func_void_PlaybackEndType(void* NON_NULL swiftClosureWrapper) noexcept;
  inline Func_void_PlaybackEndType_Wrapper wrap_Func_void_PlaybackEndType(Func_void_PlaybackEndType value) noexcept {
    return Func_void_PlaybackEndType_Wrapper(std::move(value));
  }
  
  // pragma MARK: std::shared_ptr<HybridSoundSpec>
  /**
   * Specialized version of `std::shared_ptr<HybridSoundSpec>`.
   */
  using std__shared_ptr_HybridSoundSpec_ = std::shared_ptr<HybridSoundSpec>;
  std::shared_ptr<HybridSoundSpec> create_std__shared_ptr_HybridSoundSpec_(void* NON_NULL swiftUnsafePointer) noexcept;
  void* NON_NULL get_std__shared_ptr_HybridSoundSpec_(std__shared_ptr_HybridSoundSpec_ cppType);
  
  // pragma MARK: std::weak_ptr<HybridSoundSpec>
  using std__weak_ptr_HybridSoundSpec_ = std::weak_ptr<HybridSoundSpec>;
  inline std__weak_ptr_HybridSoundSpec_ weakify_std__shared_ptr_HybridSoundSpec_(const std::shared_ptr<HybridSoundSpec>& strong) noexcept { return strong; }
  
  // pragma MARK: Result<std::shared_ptr<Promise<std::string>>>
  using Result_std__shared_ptr_Promise_std__string___ = Result<std::shared_ptr<Promise<std::string>>>;
  inline Result_std__shared_ptr_Promise_std__string___ create_Result_std__shared_ptr_Promise_std__string___(const std::shared_ptr<Promise<std::string>>& value) noexcept {
    return Result<std::shared_ptr<Promise<std::string>>>::withValue(value);
  }
  inline Result_std__shared_ptr_Promise_std__string___ create_Result_std__shared_ptr_Promise_std__string___(const std::exception_ptr& error) noexcept {
    return Result<std::shared_ptr<Promise<std::string>>>::withError(error);
  }
  
  // pragma MARK: Result<void>
  using Result_void_ = Result<void>;
  inline Result_void_ create_Result_void_() noexcept {
    return Result<void>::withValue();
  }
  inline Result_void_ create_Result_void_(const std::exception_ptr& error) noexcept {
    return Result<void>::withError(error);
  }
  
  // pragma MARK: Result<std::string>
  using Result_std__string_ = Result<std::string>;
  inline Result_std__string_ create_Result_std__string_(const std::string& value) noexcept {
    return Result<std::string>::withValue(value);
  }
  inline Result_std__string_ create_Result_std__string_(const std::exception_ptr& error) noexcept {
    return Result<std::string>::withError(error);
  }

} // namespace margelo::nitro::sound::bridge::swift
