//--------------------------------------------------------------------------------------------------
//
//	WIN-BLUETOOTH
//
//--------------------------------------------------------------------------------------------------
//
// The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//--------------------------------------------------------------------------------------------------
//
// Copyright (c) 2018 Nic Holthaus
//
//--------------------------------------------------------------------------------------------------
//
// ATTRIBUTION:
// https://github.com/martinmoene/gsl-lite/releases
//
//--------------------------------------------------------------------------------------------------
//
/// @file	obexResponse.h
/// @brief	OBEX server response classes
//
//--------------------------------------------------------------------------------------------------

#pragma once
#ifndef obexResponse_h__
#define obexResponse_h__

//-------------------------
//	INCLUDES
//-------------------------

#include <QObject>
#include <gsl-lite.h>
#include <obexHeader.h>

//-------------------------
//	FORWARD DECLARATIONS
//-------------------------

class QDataStream;

//--------------------------------------------------------------------------------------------------
//	OBEXResponse
//--------------------------------------------------------------------------------------------------
class OBEXResponse
{
	Q_GADGET

public:

	friend QDataStream& operator>>(QDataStream& in, OBEXResponse& response);

	// OBEX operation response codes. See OBEX standard chapter 3.2.1
	class Code
	{
	public:

		enum class Enum : quint8
		{
			INVALID					= 0x00,
			CONTINUE				= 0x90,
			SUCCESS					= 0xA0,
			SERVICEUNAVAILABLE		= 0xD3,
		};

		Code(quint8 value);
		operator quint8() const;
		bool isFinal() const;
		bool operator==(const Code& other) const;
		bool operator!=(const Code& other) const;

	private:

		Code::Enum	m_code;
		bool		m_isFinal = false;
	};

public:

	OBEXResponse() = default;
	virtual ~OBEXResponse() = default;
	virtual gsl::string_span data() = 0;	// returns a span representing the response-specific data storage
	virtual quint16 packetLength() = 0;		// packet length value from the response data
	virtual bool validateAndFixup() = 0;	// called at the end of operator>>. Used to validate code fields, and convert
											// large types from big to little endian. Returns true on success.
	bool isValid() const;

protected:

	bool m_valid = false;
	std::vector<OBEXHeader>	m_optionalHeaders;
};

QDataStream& operator>>(QDataStream& in, OBEXResponse& response);

//--------------------------------------------------------------------------------------------------
//	OBEXConnectResponse
//--------------------------------------------------------------------------------------------------

class OBEXConnectResponse : public OBEXResponse
{
public:

	OBEXConnectResponse() = default;
	virtual ~OBEXConnectResponse() = default;
	virtual gsl::string_span data() override;
	virtual quint16 packetLength() override;	// the return value will generally not be valid until after data has been streamed into the class.
	virtual bool validateAndFixup() override;
	quint16 maxPacketLength() const;

private:

#pragma pack(push, 1)
	struct Data
	{
		OBEXResponse::Code::Enum    code			= Code::Enum::INVALID;
		quint16						length			= 0;
		quint8						version			= 0;
		quint8						flags			= 0;
		quint16						maxPacketLength = 0;
	} m_data;
#pragma pack(pop)
};

//--------------------------------------------------------------------------------------------------
//	OBEXDisconnectResponse
//--------------------------------------------------------------------------------------------------

class OBEXDisconnectResponse : public OBEXResponse
{
public:

	OBEXDisconnectResponse() = default;
	virtual ~OBEXDisconnectResponse() = default;

	virtual gsl::string_span data() override;
	virtual quint16 packetLength() override;
	virtual bool validateAndFixup() override;

#pragma pack(push, 1)
	struct Data
	{
		OBEXResponse::Code::Enum    code = Code::Enum::SUCCESS;
		quint16						length = 0;
	} m_data;
#pragma pack(pop)
};

//--------------------------------------------------------------------------------------------------
//	OBEXPutResponse
//--------------------------------------------------------------------------------------------------

class OBEXPutResponse : public OBEXResponse
{
public:

	OBEXPutResponse() = default;
	virtual ~OBEXPutResponse() = default;

	virtual gsl::string_span data() override;
	virtual quint16 packetLength() override;
	virtual bool validateAndFixup() override;
	bool continueSending() const;

protected:

#pragma pack(push, 1)
	struct Data
	{
		OBEXResponse::Code::Enum    code = Code::Enum::CONTINUE;	// assume success until proven otherwise
		quint16						length = 0;
	} m_data;
#pragma pack(pop)

};
#endif // obexResponse_h__


// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#pragma once

#include <memory>
#include <numeric>
#include <algorithm>
#include <vector>
#include <string>
#include <limits>
#include <memory>
#include <optional>
#include <list>
#include <map>
#include <deque>
#include <chrono>
#include <variant>
#include <cassert>

#include <wrl/client.h>
#include <wrl/implements.h>

#include <wil/wrl.h>
#include <wil/result.h>

#include <gsl/gsl>

#include <d3d12.h>
#include <d3d12sdklayers.h>
#include "External/D3DX12/d3dx12.h"

#include <DirectML.h>
#include "core/common/common.h"
#include "ErrorHandling.h"

// DirectML helper libraries
#include "External/DirectMLHelpers/ApiTraits.h"
#include "External/DirectMLHelpers/ApiHelpers.h"
#include "External/DirectMLHelpers/DirectMLSchema.h"
#include "External/DirectMLHelpers/AbstractOperatorDesc.h"
#include "External/DirectMLHelpers/GeneratedSchemaTypes.h"
#include "External/DirectMLHelpers/SchemaHelpers.h"
#include "External/DirectMLHelpers/GeneratedSchemaHelpers.h"

using Microsoft::WRL::ComPtr;

// Windows pollutes the macro space, causing a build break in schema.h.
#undef OPTIONAL

#include "core/providers/dml/DmlExecutionProvider/inc/DmlExecutionProvider.h"
#include "core/providers/dml/OperatorAuthorHelper/MLOperatorAuthorHelper.h"
#include "core/providers/dml/OperatorAuthorHelper/Common.h"

#include "DmlCommon.h"
#include "TensorDesc.h"
#include "DescriptorPool.h"
#include "IExecutionProvider.h"


/* -----------------------------------------------------------------------------
 * Copyright 2021 Jonathan Haigh
 * SPDX-License-Identifier: MIT
 * ---------------------------------------------------------------------------*/

#ifndef SQ_INCLUDE_GUARD_system_linux_SqTypeSchemaImpl_h_
#define SQ_INCLUDE_GUARD_system_linux_SqTypeSchemaImpl_h_

#include "core/typeutil.h"
#include "system/SqTypeSchema.gen.h"

#include "system/schema.h"

#include <gsl/gsl>

namespace sq::system::linux {

class SqTypeSchemaImpl : public SqTypeSchema<SqTypeSchemaImpl> {
public:
  explicit SqTypeSchemaImpl(const TypeSchema &type_schema);

  SQ_ND Result get_name() const;
  SQ_ND Result get_doc() const;
  SQ_ND Result get_fields() const;

  SQ_ND Primitive to_primitive() const override;

private:
  gsl::not_null<const TypeSchema *> type_schema_;
};

} // namespace sq::system::linux

#endif // SQ_INCLUDE_GUARD_system_linux_SqTypeSchemaImpl_h_


/* -----------------------------------------------------------------------------
 * Copyright 2021 Jonathan Haigh
 * SPDX-License-Identifier: MIT
 * ---------------------------------------------------------------------------*/

#ifndef SQ_INCLUDE_GUARD_system_linux_SqParamSchemaImpl_h_
#define SQ_INCLUDE_GUARD_system_linux_SqParamSchemaImpl_h_

#include "core/typeutil.h"
#include "system/SqParamSchema.gen.h"
#include "system/schema.h"

#include <gsl/gsl>

namespace sq::system::linux {

class SqParamSchemaImpl : public SqParamSchema<SqParamSchemaImpl> {
public:
  explicit SqParamSchemaImpl(const ParamSchema &param_schema);

  SQ_ND Result get_name() const;
  SQ_ND Result get_doc() const;
  SQ_ND Result get_index() const;
  SQ_ND Result get_type() const;
  SQ_ND Result get_required() const;
  SQ_ND Result get_default_value() const;
  SQ_ND Result get_default_value_doc() const;

  SQ_ND Primitive to_primitive() const override;

private:
  gsl::not_null<const ParamSchema *> param_schema_;
};

} // namespace sq::system::linux

#endif // SQ_INCLUDE_GUARD_system_linux_SqParamSchemaImpl_h_


#ifndef VMICORE_VMIINITDATA_H
#define VMICORE_VMIINITDATA_H

#include <filesystem>
#include <gsl/pointers>
#include <libvmi/libvmi.h>

class VmiInitData
{
  public:
    gsl::owner<vmi_init_data_t*> data{};

    explicit VmiInitData(const std::filesystem::path& socketPath);

    ~VmiInitData();
};

#endif // VMICORE_VMIINITDATA_H


#pragma once

#include "HttpHeaders.h"
#include "Library.h"

#include <gsl/span>

#include <cstddef>
#include <map>
#include <string>

namespace CesiumAsync {

/**
 * @brief A completed response for a 3D Tiles asset.
 */
class CESIUMASYNC_API IAssetResponse {
public:
  /**
   * @brief Default destructor
   */
  virtual ~IAssetResponse() = default;

  /**
   * @brief Returns the HTTP response code.
   */
  virtual uint16_t statusCode() const = 0;

  /**
   * @brief Returns the HTTP content type
   */
  virtual std::string contentType() const = 0;

  /**
   * @brief Returns the HTTP headers of the response
   */
  virtual const HttpHeaders& headers() const = 0;

  /**
   * @brief Returns the data of this response
   */
  virtual gsl::span<const std::byte> data() const = 0;
};

} // namespace CesiumAsync


#pragma once
/*
 * (C) Copyright 2020-2021 UCAR
 *
 * This software is licensed under the terms of the Apache Licence Version 2.0
 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
 */
/*! \defgroup ioda_cxx_layout Groups and Data Layout
 * \brief Public API for ioda::Group, ioda::ObsGroup, and data layout policies.
 * \ingroup ioda_cxx_api
 *
 * @{
 * \file Group.h
 * \brief Interfaces for ioda::Group and related classes.
 */

#include <gsl/gsl-lite.hpp>
#include <map>
#include <memory>
#include <string>
#include <vector>

#include "ioda/Attributes/Has_Attributes.h"
#include "ioda/Types/Has_Types.h"
#include "ioda/Variables/FillPolicy.h"
#include "ioda/Variables/Has_Variables.h"
#include "ioda/defs.h"

namespace ioda {
class Group;

namespace Engines {
struct Capabilities;
}  // namespace Engines

namespace detail {
class Group_Base;
class Group_Backend;

/// \brief Hidden base class to prevent constructor confusion.
/// \ingroup ioda_cxx_layout
/// \note enable_shared_from_this is a hint to pybind11.
class IODA_DL Group_Base {
  std::shared_ptr<Group_Backend> backend_;

protected:
  Group_Base(std::shared_ptr<Group_Backend>);

public:
  virtual ~Group_Base();

  std::shared_ptr<Group_Backend> getBackend() const { return backend_; }

  /// Get capabilities of the Engine backing this Group
  virtual ::ioda::Engines::Capabilities getCapabilities() const;

  /// \brief Get the fill value policy used for Variables within this Group
  /// \details The backend has to be consulted for this operation. Storage of this policy is
  ///   backend-dependent.
  virtual FillValuePolicy getFillValuePolicy() const;

  /// \brief List all one-level child groups in this group
  /// \details This function exists to provide the same calling semantics as
  ///   vars.list() and atts.list(). It is useful for human exploration of the contents
  ///   of a Group.
  /// \returns A vector of strings listing the child groups. The strings are unordered.
  /// \see listObjects if you need to enumerate both Groups and Variables, or
  ///   if you want to do a recursive search. This function is more sophisticated, and
  ///   depending on the backend it may be faster than recursive calls to
  ///   list() and vars.list().
  std::vector<std::string> list() const;
  /// Same as list(). Uniform semantics with atts() and vars().
  inline std::vector<std::string> groups() const { return list(); }

  /// \brief List all objects (groups + variables) within this group
  /// \param recurse indicates whether the search should be one-level or recursive. If
  ///   multiple possible paths exist for an object, only one is actually returned.
  /// \param filter allows you to search for only a certain type of object, such as a
  ///   Group or Variable.
  /// \returns a map of ObjectTypes. Each mapping contains a vector of strings indicating
  ///   object names. If a filter is provided, then this map only contains the filtered
  ///   object type. Otherwise, the map always has vectors for each element of ObjectType
  ///   (Group, Variable, etc.), although these vectors may be empty if no object of a
  ///   certain type is found.
  /// \todo This function should list all *distinct* objects. In the future, this will mean
  ///   that 1) hard-linked duplicate objects will only be listed once, 2) soft
  ///   links pointing to the same object will only be traversed once, and
  ///   3) multiple external links to the same object will only be traversed once.
  ///   If you would want to list *indistinct* objects, then there will be a
  ///   listLinks function.
  /// \todo Once links are implemented, add an option to auto-resolve
  ///   soft and external links.
  virtual std::map<ObjectType, std::vector<std::string>> listObjects(ObjectType filter
                                                                     = ObjectType::Ignored,
                                                                     bool recurse = false) const;

  template <ObjectType objectClass>
  std::vector<std::string> listObjects(bool recurse = false) const {
    return listObjects(objectClass, recurse)[objectClass];
  }

  /// Does a group exist at the specified path?
  /// \param name is the group name.
  /// \returns true if a group does exist.
  /// \return false if a group does not exist.
  virtual bool exists(const std::string& name) const;

  /// \brief Create a group
  /// \param name is the group name.
  /// \returns an invalid handle on failure. (i.e. return.isGroup() == false).
  /// \returns a scoped handle to the group on success.
  virtual Group create(const std::string& name);

  /// \brief Open a group
  /// \returns an invalid handle if an error occurred. (i.e. return.isGroup() == false).
  /// \returns a scoped handle to the group upon success.
  /// \note It is possible to have multiple handles opened for the group
  /// simultaneously.
  /// \param name is the name of the child group to open.
  virtual Group open(const std::string& name) const;

  /// Use this to access the metadata for the group / ObsSpace.
  Has_Attributes atts;

  /// Use this to access named data types.
  Has_Types types;

  /// Use this to access variables
  Has_Variables vars;
};

class IODA_DL Group_Backend : public Group_Base {
public:
  virtual ~Group_Backend();
  /// Default fill value policy is NETCDF4. Overridable on a per-backend basis.
  FillValuePolicy getFillValuePolicy() const override;

  /// @}

protected:
  Group_Backend();
};

}  // namespace detail

/** \brief Groups are a new implementation of ObsSpaces.
 * \ingroup ioda_cxx_layout
 *
 * \see \ref Groups for a examples.
 *
 * A group can be thought of as a folder that contains Variables and Metadata.
 * A group can also contain child groups, allowing for our ObsSpaces to exist in a
 * nested tree-like structure, which removes the need for having an ObsSpaceContainer.
 *
 * Groups are implemented in several backends, such as the in-memory IODA store, the HDF5 disk
 * backend, the HDF5 in-memory backend, the ATLAS backend, et cetera. The root Group is mounted
 * using one of these backends (probably as a File object, which is a special type of Group),
 * and additional backends may be mounted into the tree structure.
 *
 * \throws std::logic_error if the backend handle points to something other than a group.
 * \throws std::logic_error if the backend handle is invalid.
 * \throws std::logic_error if any error has occurred.
 * \author Ryan Honeyager (honeyage@ucar.edu)
 **/
class IODA_DL Group : public detail::Group_Base {
public:
  Group();
  Group(std::shared_ptr<detail::Group_Backend>);
  virtual ~Group();
};

}  // namespace ioda

/// @}


#ifndef VKST_PLAT_FS_NOTIFY_WIN32_H
#define VKST_PLAT_FS_NOTIFY_WIN32_H

#ifndef VKST_PLAT_FS_NOTIFY_H
#error "Include fs_notify.h only"
#endif

#include "fs_notify.h"
#include <gsl.h>
#include <vector>

namespace plat {

class fs_notify final : public impl::fs_notify<fs_notify> {
public:
  class watch {
  public:
    OVERLAPPED overlapped{};
    plat::filesystem::path path{};
    notify_delegate delegate{};
    bool recursive{false};
    HANDLE handle{INVALID_HANDLE_VALUE};
    std::array<BYTE, 32 * 1024> buffer{};
    watch_id id{UINT32_MAX};
    bool stop{false};

    bool refresh(bool clear = false) noexcept;
    void notify(plat::filesystem::path changed_path, DWORD action) noexcept;

    watch(plat::filesystem::path p, notify_delegate d, bool r) noexcept
    : path{std::move(p)}, delegate{std::move(d)}, recursive{r} {}

    watch() = default;
    watch(watch const&) = delete;
    watch& operator=(watch const&) = delete;
    ~watch() noexcept;
  }; // struct watch

private:
  std::vector<gsl::unique_ptr<watch>> _watches;

  watch_id do_add(plat::filesystem::path path,
                  impl::fs_notify<fs_notify>::notify_delegate delegate,
                  bool recursive, std::error_code& ec) noexcept;

  void do_remove(watch_id id) noexcept;

  void do_tick() noexcept;

  friend class impl::fs_notify<fs_notify>;
}; // class fs_notify

} // namespace plat

#endif // VKST_PLAT_FS_NOTIFY_WIN32_H


#ifndef COMMAND_LINE_INCLUDE
#define COMMAND_LINE_INCLUDE

#include <string>
#include <vector>

#include <gsl/string_span>

#include "config/fleetingOptionsInterface.h"
#include "config/variablesMap.h"
#include "core/task.h"

namespace execHelper {
namespace plugins {
using CommandLineArg = std::string;
using CommandLineArgs = std::vector<CommandLineArg>;

static const gsl::czstring<> COMMAND_LINE_KEY = "command-line";

/**
 * \brief Extends the functionality to include the _command-line_ config parameter and processes this parameter
 */
struct CommandLine {
    /*! @copydoc AddEnvironment::getVariables(config::VariablesMap&, const config::FleetingOptionsInterface&)
     */
    static void
    getVariables(config::VariablesMap& variables,
                 const config::FleetingOptionsInterface& options) noexcept;

    /*! @copydoc JobsLong::apply(core::Task&, const config::VariablesMap&)
     */
    inline static void apply(core::Task& task,
                             const config::VariablesMap& variables) noexcept {
        task.append(*(variables.get<CommandLineArgs>(COMMAND_LINE_KEY)));
    }
};

} // namespace plugins
} // namespace execHelper

#endif /* COMMAND_LINE_INCLUDE */


#include <stdlib.h>
#include <gsl/gsl_vector.h>
#include "../include/type.h"
#include "../include/global.h"
#include "../include/cthreadpool.h"

void *pool_thread(void *arg) {
    threadpool_t *pool = (threadpool_t*)arg;
    task_t task;
    int head;

    while(1) {
        pthread_mutex_lock(&(pool->pool_lock));

        while(pool->task_count == 0 && pool->flag != POOL_RECLAIM) {
            pthread_cond_wait(&(pool->notify), &(pool->pool_lock));
        }

        if (pool->task_count == 0 && pool->flag == POOL_RECLAIM) {
            break;
        }

        head = pool->task_head;
        task.func = pool->tasks[head].func;
        task.arg = pool->tasks[head].arg;
        pool->task_head++;
        pool->task_count--;

        pthread_mutex_unlock(&(pool->pool_lock));

        *(pool->tasks[head].ret) = (task.func)(task.arg);
    }

    pthread_mutex_unlock(&(pool->pool_lock));

    return NULL;
}

threadpool_t* threadpool_create(const int nthread, const int queue_size) {
    int i = 0;
    threadpool_t *pool = NULL;

    if ((pool = (threadpool_t *)malloc(sizeof(threadpool_t))) == NULL) {
        return NULL;
    }

    pool->nthread = nthread;
    pool->queue_size = queue_size;
    pool->task_head = 0;
    pool->task_tail = -1;
    pool->task_count = 0;

    pthread_mutex_init(&pool->pool_lock, NULL);
    pthread_cond_init(&pool->notify, NULL);

    pool->working = (int*)malloc(sizeof(int)*nthread);
    pool->threads = (pthread_t*)malloc(sizeof(pthread_t)*nthread);
    pool->tasks = (task_t*)malloc(sizeof(task_t)*queue_size);
    for (i = 0; i < nthread; ++i) {
        pool->working[i] = IDLE;
    }

    for(i = 0; i < nthread; i++) {
        if(pthread_create(&(pool->threads[i]), NULL, pool_thread, (void*)pool) != 0) {
            threadpool_reclaim(pool);
            return NULL;
        }
        pool->working[i] = INCOMPLETED;
    }

    return pool;
}

int threadpool_add(threadpool_t *pool, void* (*func)(void *), void *arg, void **ret) {
    int tail;

    if (pool == NULL || func == NULL) {
        return POOL_ADD_ERR;
    }

    if(pthread_mutex_lock(&(pool->pool_lock)) != 0) {
        return POOL_LOCK_FAILURE;
    }

    tail = pool->task_tail + 1;
    tail = tail == pool->queue_size? 0:tail;
    if (pool->task_count == pool->queue_size) {
        // TODO erroneous.
        if ((realloc(pool->tasks, 2 * pool->queue_size)) != 0) {
            return POOL_ADD_ERR;
        }
        tail = pool->queue_size;
        pool->queue_size *= 2;
    }

    pool->tasks[tail].func = func;
    pool->tasks[tail].arg = arg;
    pool->tasks[tail].ret = ret;
    pool->task_tail = tail;
    pool->task_count++;

    if(pthread_cond_signal(&(pool->notify)) != 0 ||
       pthread_mutex_unlock(&pool->pool_lock) != 0) {
        return POOL_LOCK_FAILURE;
    }

    return 0;
}

int threadpool_reclaim(threadpool_t *pool) {
    int i = 0;

    if(pthread_mutex_lock(&(pool->pool_lock)) != 0) {
        return POOL_LOCK_FAILURE;
    }

    pool->flag = POOL_RECLAIM;
    pthread_mutex_unlock(&(pool->pool_lock));

    for (i = 0; i < pool->nthread; ++i) {
        if (pool->working[i] != IDLE) {
            pthread_join(pool->threads[i], NULL);
        }
    }

    free(pool->threads);
    free(pool->tasks);
    free(pool);

    return 0;
}


#pragma once

#include "JsonHandler.h"
#include "Library.h"

#include <gsl/span>

#include <cstddef>
#include <optional>
#include <string>
#include <vector>

namespace rapidjson {
struct MemoryStream;
}

namespace CesiumJsonReader {

/**
 * @brief The result of {@link Reader::readJson}.
 */
template <typename T> struct ReadJsonResult {
  /**
   * @brief The value read from the JSON, or `std::nullopt` on error.
   */
  std::optional<T> value;

  /**
   * @brief Errors that occurred while reading.
   */
  std::vector<std::string> errors;

  /**
   * @brief Warnings that occurred while reading.
   */
  std::vector<std::string> warnings;
};

/**
 * @brief Reads JSON.
 */
class CESIUMJSONREADER_API JsonReader {
public:
  /**
   * @brief Reads JSON from a byte buffer.
   *
   * @param data The buffer from which to read JSON.
   * @param handler The handler to receive the top-level JSON object.
   * @return The result of reading the JSON.
   */
  template <typename T>
  static ReadJsonResult<typename T::ValueType>
  readJson(const gsl::span<const std::byte>& data, T& handler) {
    ReadJsonResult<typename T::ValueType> result;

    result.value.emplace();

    FinalJsonHandler finalHandler(result.warnings);
    handler.reset(&finalHandler, &result.value.value());

    JsonReader::internalRead(
        data,
        handler,
        finalHandler,
        result.errors,
        result.warnings);

    if (!result.errors.empty()) {
      result.value.reset();
    }

    return result;
  }

private:
  class FinalJsonHandler : public JsonHandler {
  public:
    FinalJsonHandler(std::vector<std::string>& warnings);
    virtual void reportWarning(
        const std::string& warning,
        std::vector<std::string>&& context) override;
    void setInputStream(rapidjson::MemoryStream* pInputStream) noexcept;

  private:
    std::vector<std::string>& _warnings;
    rapidjson::MemoryStream* _pInputStream;
  };

  static void internalRead(
      const gsl::span<const std::byte>& data,
      IJsonHandler& handler,
      FinalJsonHandler& finalHandler,
      std::vector<std::string>& errors,
      std::vector<std::string>& warnings);
};

} // namespace CesiumJsonReader


#pragma once

#include <list>
#include <vector>
#include <optional>
#include <memory>
#include <functional>

#include <gsl/gsl-lite.hpp>

#include "UtilMacros.Namespace.h"
#include "util.std_aliases.h"
#include "zstring_view.h"

NAMESPACE_BEGIN( cpp )

using vlr::string;
using vlr::wstring;
using vlr::tstring;
using vlr::zstring_view;
using vlr::wzstring_view;
using vlr::tzstring_view;

using std::shared_ptr;
using std::weak_ptr;
using std::make_shared;

using std::function;

using gsl::span;

NAMESPACE_END //( cpp )


#pragma once

#include <CesiumAsync/IAssetResponse.h>

#include <gsl/span>

#include <string>
#include <vector>

namespace CesiumCpp {

namespace CesiumNativeImpl {
/**
 * @brief Implementation of an IAssetResponse for data from a file.
 */
class FileAssetResponse : public CesiumAsync::IAssetResponse {
public:
  /**
   * @brief Creates a new instance.
   *
   * @param fileName The file name.
   * @param statusCode The HTTP status code
   * @param contentType The content type.
   * @param fileData The file data.
   */
  FileAssetResponse(const std::string &fileName, uint16_t statusCode,
                    const std::string &contentType,
                    const CesiumAsync::HttpHeaders &headers,
                    const std::vector<std::byte> &fileData);

  uint16_t statusCode() const noexcept override;

  virtual const CesiumAsync::HttpHeaders &headers() const override {
    return this->_headers;
  }

  std::string contentType() const noexcept override;

  gsl::span<const std::byte> data() const noexcept override;

private:
  std::string _fileName;
  uint16_t _statusCode;
  std::string _contentType;
  CesiumAsync::HttpHeaders _headers;

  std::vector<std::byte> _fileData;
};
} // namespace CesiumNativeImpl
} // namespace CesiumCpp


/// @file Error.h
/// @author Braxton Salyer <braxtonsalyer@gmail.com>
/// @brief Basic high-level types for communicating recoverable errors
/// @version 0.1
/// @date 2021-11-03
///
/// MIT License
/// @copyright Copyright (c) 2021 Braxton Salyer <braxtonsalyer@gmail.com>
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to
/// deal in the Software without restriction, including without limitation the
/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
/// sell copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
/// IN THE SOFTWARE.
#pragma once

#include <Hyperion/BasicTypes.h>
#include <Hyperion/HyperionDef.h>
#include <Hyperion/Ignore.h>
#include <Hyperion/Memory.h>
#include <Hyperion/error/SystemDomain.h>
#include <cstring>
#include <gsl/gsl>
#include <memory>
#include <string>
#include <system_error>
#include <type_traits>

///	@defgroup error Error
/// The Error module provides various error-handling facilities and types for
/// communicating and handling recoverable errors and for aborting on
/// irrecoverable errors in a communicable way
/// @headerfile "Hyperion/Error.h"

namespace hyperion::error {
	using namespace std::literals::string_literals;

	/// @brief Basic interface for recoverable errors. Error types may provide
	/// additional functionality beyond this, but this much is required.
	/// @ingroup error
	/// @headerfile "Hyperion/Error.h"
	IGNORE_WEAK_VTABLES_START

	class [[nodiscard]] ErrorBase {
	  public:
		constexpr ErrorBase() noexcept = default;

		constexpr ErrorBase(const ErrorBase&) noexcept = default;

		constexpr ErrorBase(ErrorBase&&) noexcept = default;

		constexpr virtual ~ErrorBase() noexcept = default;

		/// @brief Returns the value of the associated error code as an `i64`
		/// @return The value of the associated error code
		/// @ingroup error
		[[nodiscard]] virtual constexpr auto value() const noexcept -> i64 = 0;

		/// @brief Returns the message associated with the error as a `std::string`
		/// @return The message associated with the error
		/// @ingroup error
		[[nodiscard]] virtual auto message() const noexcept -> std::string = 0;

		/// @brief Converts this error into a `std::string`
		/// @return This error as a `std::string`
		/// @ingroup error
		[[nodiscard]] virtual auto to_string() const noexcept -> std::string = 0;

		constexpr auto operator=(const ErrorBase&) noexcept -> ErrorBase& = default;

		constexpr auto operator=(ErrorBase&&) noexcept -> ErrorBase& = default;
	};

	IGNORE_WEAK_VTABLES_STOP

	// class [[nodiscard]] AnyError;

	/// @brief General purpose type for communicating recoverable errors.
	///
	/// Wraps an `error::ErrorCode<Domain>` in a type-safe manner.
	/// Usually makes up the `E` variant of a `Result<T, E>`
	///
	/// @tparam Domain - The `StatusCodeDomain` associated with the this error
	/// @ingroup error
	template<StatusCodeDomain Domain = SystemDomain>
	class [[nodiscard]] Error final : public ErrorBase {
	  public:
		/// @brief The type used to represent the error (an enum, integer error code,
		/// etc)
		/// @ingroup error
		using value_type = typename ErrorCode<Domain>::value_type;

		friend class AnyError;

		/// @brief Constructs a default `Error` with an error code representing an
		/// unknown error
		/// @ingroup error
		constexpr Error() noexcept {

			if constexpr(StatusCodeEnum<value_type>) {
				m_error_code = make_error_code(static_cast<value_type>(-1));
			}
			else {
				m_error_code = make_error_code<Domain>(static_cast<value_type>(-1));
			}
		}

		/// @brief Constructs an `Error` from the given `ErrorCode<Domain>`
		///
		/// @param code - The error code
		/// @ingroup error
		constexpr Error(const ErrorCode<Domain>& code) noexcept // NOLINT
			: m_error_code(code) {
		}

		/// @brief Constructs an `Error` from the given `ErrorCode<Domain>`
		///
		/// @param code - The error code
		/// @ingroup error
		constexpr Error(ErrorCode<Domain>&& code) noexcept // NOLINT
			: m_error_code(std::move(code)) {
		}

		/// @brief Constructs an `Error` from the given error code
		///
		/// @param code - The error code
		/// @ingroup error
		constexpr Error(const value_type& code) noexcept // NOLINT
			requires(!StatusCodeEnum<value_type>)
			: m_error_code(make_error_code<Domain>(code)) {
		}

		/// @brief Constructs an `Error` from the given error code
		///
		/// @param code - The error code
		/// @ingroup error
		constexpr Error(const value_type& code) noexcept // NOLINT
			requires StatusCodeEnum<value_type> : m_error_code(make_error_code(code)) {
		}

		/// @brief Copy-constructs an `Error`
		/// @ingroup error
		constexpr Error(const Error& error) = default;

		/// @brief Move-constructs an `Error`
		/// @ingroup error
		constexpr Error(Error&& error) noexcept = default;

		/// @brief Destroys this `Error`
		/// @ingroup error
		constexpr ~Error() noexcept final = default;

		/// @brief Returns the `i64` value of the error code associated with this
		/// `Error`
		///
		/// @return The associated error code as an `i64`
		/// @ingroup error
		[[nodiscard]] auto value() const noexcept -> i64 final {

			return m_error_code.value();
		}

		/// @brief Returns the `ErrorCode` associated with this `Error`
		///
		/// @return The associated `ErrorCode`
		/// @ingroup error
		[[nodiscard]] auto code() const noexcept -> const ErrorCode<Domain>& {

			return m_error_code;
		}

		/// @brief Returns the error message associated with this `Error`
		///
		/// @return The error message
		/// @ingroup error
		[[nodiscard]] inline auto message() const noexcept -> std::string final {

			if constexpr(concepts::Same<error_code_message_type, std::string>) {
				return m_error_code.message();
			}
			else {
				return std::string(m_error_code.message());
			}
		}

		/// @brief Returns the error message associated with this `Error`, as a cstring
		///
		/// @return The error message
		/// @ingroup error
		[[nodiscard]] auto message_as_cstr() const noexcept -> const char* {

			return m_error_code.message().c_str();
		}

		/// @brief Gets the `std::string` representation of this `Error`
		///
		/// @return this `Error` formatted as a `std::string`
		/// @ingroup error
		[[nodiscard]] auto to_string() const noexcept -> std::string final {

			return fmt::format("Error: {}", m_error_code.message());
		}

		/// @brief Converts this `Error` into its underlying `ErrorCode<Domain>`
		/// @ingroup error
		constexpr operator ErrorCode<Domain>() const noexcept { // NOLINT
			return m_error_code;
		}

		/// @brief Converts this `Error` into its underlying `value_type`
		/// @ingroup error
		constexpr operator value_type() const noexcept { // NOLINT
			return static_cast<value_type>(m_error_code);
		}

		/// @brief Equality comparison operator with another `Error` from a possibly different
		/// `StatusCodeDomain`
		/// @tparam Domain2 - The `StatusCodeDomain` of `error`
		/// @ingroup error
		template<StatusCodeDomain Domain2>
		constexpr auto operator==(const Error<Domain2>& error) const noexcept -> bool {
			return m_error_code == error.m_error_code;
		}

		/// @brief Inequality comparison operator with another `Error` from a possibly different
		/// `StatusCodeDomain`
		/// @tparam Domain2 - The `StatusCodeDomain` of `error`
		/// @ingroup error
		template<StatusCodeDomain Domain2>
		constexpr auto operator!=(const Error<Domain2>& error) const noexcept -> bool {
			return m_error_code != error.m_error_code;
		}

		/// @brief Equality comparison operator with an `ErrorCode` from a possibly different
		/// `StatusCodeDomain`
		/// @tparam Domain2 - The `StatusCodeDomain` of `code`
		/// @ingroup error
		template<StatusCodeDomain Domain2>
		constexpr auto operator==(const ErrorCode<Domain2>& code) const noexcept -> bool {
			return m_error_code == code;
		}

		/// @brief Inequality comparison operator with an `ErrorCode` from a possibly different
		/// `StatusCodeDomain`
		/// @tparam Domain2 - The `StatusCodeDomain` of `code`
		/// @ingroup error
		template<StatusCodeDomain Domain2>
		constexpr auto operator!=(const ErrorCode<Domain2>& code) const noexcept -> bool {
			return m_error_code != code;
		}

		/// @brief Copy-assigns the given `error` to this `Error`
		/// @ingroup error
		constexpr auto operator=(const Error& error) noexcept -> Error& = default;

		/// @brief Move-assigns the given `error` to this `Error`
		/// @ingroup error
		constexpr auto operator=(Error&& error) noexcept -> Error& = default;

		/// @brief Copy-assigns the given `ErrorCode<Domain>` to this `Error`
		/// @ingroup error
		constexpr auto operator=(const ErrorCode<Domain>& code) noexcept -> Error& {

			m_error_code = code;

			return *this;
		}

		/// @brief Move-assigns the given `ErrorCode<Domain>` to this `Error`
		/// @ingroup error
		constexpr auto operator=(ErrorCode<Domain>&& code) noexcept -> Error& {

			m_error_code = std::move(code);

			return *this;
		}

		/// @brief Provides `std::tuple`-like structured binding support.
		///
		/// `Index == 0` returns the error code value.
		/// `Index == 1` returns the error message.
		/// Other `Index` values ar invalid
		///
		/// @return The error code value (`Index == 0`), or the error message (`Index
		/// == 1`)
		/// @ingroup error
		template<usize Index>
		auto get() const&& noexcept {

			return get_impl<Index>(*this);
		}

		/// @brief Provides `std::tuple`-like structured binding support.
		///
		/// `Index == 0` returns the error code value.
		/// `Index == 1` returns the error message.
		/// Other `Index` values ar invalid
		///
		/// @return The error code value (`Index == 0`), or the error message (`Index
		/// == 1`)
		/// @ingroup error
		template<usize Index>
		auto get() const& noexcept {

			return get_impl<Index>(*this);
		}

	  private:
		template<usize Index, typename T>
		auto get_impl(T&& t) const noexcept {

			static_assert(Index < 2, "Index out of bounds for hyperion::error::Error::get");
			if constexpr(Index == 0) {
				return std::forward<T>(t).m_error_code.value();
			}
			else {
				return std::forward<T>(t).m_error_code.message();
			}
		}

		/// error code
		ErrorCode<Domain> m_error_code;

		using error_code_message_type = decltype(m_error_code.message());
	};
} // namespace hyperion::error

/// @brief Specialize `std::tuple_size` for `error::Error<Domain>`
/// @ingroup error
template<hyperion::error::StatusCodeDomain Domain>
struct std::tuple_size<hyperion::error::Error<Domain>> {
	static constexpr hyperion::usize value = 2;
};

/// @brief Specialize `std::tuple_element<0, T>` for `error::Error<Domain>`
/// @ingroup error
template<hyperion::error::StatusCodeDomain Domain>
struct std::tuple_element<0, hyperion::error::Error<Domain>> {
	using type = typename hyperion::error::Error<Domain>::value_type;
};

/// @brief Specialize `std::tuple_element<1, T>` for `error::Error<Domain>`
/// @ingroup error
template<hyperion::error::StatusCodeDomain Domain>
struct std::tuple_element<1, hyperion::error::Error<Domain>> {
	using type = std::string;
};

namespace hyperion::error {

	/// @brief `SystemError` is an error representing the default platform/OS level
	/// errors (eg POSIX or WIN32 error codes)
	///
	/// In practice, this will usually be an alias for one of `PosixError`,
	/// `Win32Error`, or `NTError`, depending on platform and configuration
	/// @ingroup error
	using SystemError = Error<SystemDomain>;
	/// @brief `PosixError` is an error representing a platform's implementation of
	/// POSIX error codes (it includes support for additional platform specific
	/// codes not required by POSIX)
	/// @ingroup error
	using PosixError = Error<PosixDomain>;
	/// @brief `GenericError` represents the strict set of POSIX required error
	/// codes.
	///
	/// In Hyperion's error system, `GenericError` fills a role similar to a
	/// `std::error_code` of `std::generic_category`
	/// @ingroup error
	using GenericError = Error<GenericDomain>;

#if HYPERION_PLATFORM_WINDOWS
	/// @brief `Win32Error` is an error representing the Win32 error codes
	/// @ingroup error
	using Win32Error = Error<Win32Domain>;
	/// @brief `NTError` is an error representing the Windows NT error codes
	/// @ingroup error
	using NTError = Error<NTDomain>;
#endif // HYPERION_PLATFORM_WINDOWS

	/// @brief Concept specifying the requirements of a type necessary to be
	/// guaranteed compatible with Hyperion's error system.
	///
	/// Users are encouraged to fulfill this concept for their own error types,
	/// particularly when using them with Hyperion's higher-level error-handling
	/// facilities like `Result<T, E>`
	/// @ingroup error
	template<typename E>
	concept ErrorType = std::derived_from<E, ErrorBase>;

	/// @brief Concept useful for shorthanding `!ErrorType<E>`
	/// @note Removes the need for extra parentheses and enables cleaner
	/// auto-formatting (eg `SomeConcept &&(!ErrorType<E>)` vs `SomeConcept &&
	/// NotErrorType<E>`)
	/// @ingroup error
	template<typename E>
	concept NotErrorType = !ErrorType<E>;

	/// @brief `AnyError` represents a type erased error from any
	/// `error::StatusCodeDomain`
	/// @ingroup error
	class [[nodiscard]] AnyError final : public ErrorBase {
	  public:
		/// @brief Constructs an `AnyError` as an unknown error
		/// @ingroup error
		HYPERION_CONSTEXPR_STRINGS AnyError() noexcept = default;

		/// @brief Constructs an `AnyError` from the given `error::ErrorCode<Domain>`
		///
		/// @tparam Domain - The `error::StatusCodeDomain` of the error
		///
		/// @param code - The error code this `AnyError` should represent
		/// @ingroup error
		template<StatusCodeDomain Domain>
		HYPERION_CONSTEXPR_STRINGS AnyError(const ErrorCode<Domain>& code) noexcept // NOLINT
			: m_error_code(code.value()), m_message(code.message()) {
		}

		/// @brief Constructs an `AnyError` from the given `error::ErrorCode<Domain>`
		///
		/// @tparam Domain - The `error::StatusCodeDomain` of the error
		///
		/// @param code - The error code this `AnyError` should represent
		/// @ingroup error
		template<StatusCodeDomain Domain>
		HYPERION_CONSTEXPR_STRINGS AnyError(ErrorCode<Domain>&& code) noexcept // NOLINT
			: m_error_code(code.value()), m_message(code.message()) {
		}

		/// @brief Constructs an `AnyError` from the given `error::Error<Domain>`
		///
		/// @tparam Domain - The `error::StatusCodeDomain` of the error
		///
		/// @param error - The error this `AnyError` should represent
		/// @ingroup error
		template<StatusCodeDomain Domain>
		HYPERION_CONSTEXPR_STRINGS AnyError(const Error<Domain>& error) noexcept // NOLINT
			: m_error_code(error.code().value()), m_message(error.message()) {
		}

		/// @brief Constructs an `AnyError` from the given `error::Error<Domain>`
		///
		/// @tparam Domain - The `error::StatusCodeDomain` of the error
		///
		/// @param error - The error this `AnyError` should represent
		/// @ingroup error
		template<StatusCodeDomain Domain>
		HYPERION_CONSTEXPR_STRINGS AnyError(Error<Domain>&& error) noexcept // NOLINT
			: m_error_code(error.code().value()), m_message(error.message()) {
		}
		/// @brief Copy-constructs an `AnyError` from the given one
		/// @ingroup error
		HYPERION_CONSTEXPR_STRINGS AnyError(const AnyError&) noexcept = default;
		/// @brief Move-constructs an `AnyError` from the given one
		/// @ingroup error
		HYPERION_CONSTEXPR_STRINGS AnyError(AnyError&&) noexcept = default;
		/// @brief Destroys this `AnyError`
		/// @ingroup error
		HYPERION_CONSTEXPR_STRINGS ~AnyError() noexcept final = default;

		/// @brief Returns the `i64` value corresponding with the error code this
		/// represents
		/// @return The error code as an `i64`
		/// @ingroup error
		[[nodiscard]] constexpr auto value() const noexcept -> i64 final {

			return m_error_code;
		}

		/// @brief Returns the error message associated with the error code this
		/// represents
		/// @return The error code message
		/// @ingroup error
		[[nodiscard]] auto message() const noexcept -> std::string final {

			return m_message;
		}

		/// @brief Returns the string representation of this `AnyError`
		/// @return this `AnyError` as a `std::string`
		/// @ingroup error
		[[nodiscard]] HYPERION_CONSTEXPR_STRINGS auto
		to_string() const noexcept -> std::string final {

			return "Error: "s + m_message + "\n"s;
		}

		/// @brief Copy-assigns the given `AnyError` to this one
		/// @ingroup error
		HYPERION_CONSTEXPR_STRINGS auto operator=(const AnyError&) noexcept -> AnyError& = default;
		/// @brief Move-assigns the given `AnyError` to this one
		/// @ingroup error
		HYPERION_CONSTEXPR_STRINGS auto operator=(AnyError&&) noexcept -> AnyError& = default;

		/// @brief Copy-assigns this `AnyError` with the given
		/// `error::ErrorCode<Domain>`
		///
		/// @tparam Domain - The `error::StatusCodeDomain` of the error code
		///
		/// @param code - The error code to assign to this
		/// @ingroup error
		template<StatusCodeDomain Domain>
		HYPERION_CONSTEXPR_STRINGS auto
		operator=(const ErrorCode<Domain>& code) noexcept -> AnyError& {

			m_error_code = code.value();
			m_message = code.message();

			return *this;
		}

		/// @brief Move-assigns this `AnyError` with the given
		/// `error::ErrorCode<Domain>`
		///
		/// @tparam Domain - The `error::StatusCodeDomain` of the error code
		///
		/// @param code - The error code to assign to this
		/// @ingroup error
		template<StatusCodeDomain Domain>
		HYPERION_CONSTEXPR_STRINGS auto operator=(ErrorCode<Domain>&& code) noexcept -> AnyError& {

			m_error_code = code.value();
			m_message = code.message();

			return *this;
		}

		/// @brief Copy-assigns this `AnyError` with the given `error::Error<Domain>`
		///
		/// @tparam Domain - The `error::StatusCodeDomain` of the error
		///
		/// @param error - The error to assign to this
		/// @ingroup error
		template<StatusCodeDomain Domain>
		HYPERION_CONSTEXPR_STRINGS auto
		operator=(const Error<Domain>& error) noexcept -> AnyError& {

			m_error_code = error.value();
			m_message = error.message();

			return *this;
		}

		/// @brief Move-assigns this `AnyError` with the given `error::Error<Domain>`
		///
		/// @tparam Domain - The `error::StatusCodeDomain` of the error
		///
		/// @param error - The error to assign to this
		/// @ingroup error
		template<StatusCodeDomain Domain>
		HYPERION_CONSTEXPR_STRINGS auto operator=(Error<Domain>&& error) noexcept -> AnyError& {

			m_error_code = error.value();
			m_message = error.message();

			return *this;
		}

		/// @brief Provides `std::tuple`-like structured binding support.
		///
		/// `Index == 0` returns the error code value.
		/// `Index == 1` returns the error message.
		/// Other `Index` values ar invalid
		///
		/// @return The error code value (`Index == 0`), or the error message (`Index
		/// == 1`)
		/// @ingroup error
		template<usize Index>
		auto get() const&& noexcept {

			return get_impl<Index>(*this);
		}

		/// @brief Provides `std::tuple`-like structured binding support.
		///
		/// `Index == 0` returns the error code value.
		/// `Index == 1` returns the error message.
		/// Other `Index` values ar invalid
		///
		/// @return The error code value (`Index == 0`), or the error message (`Index
		/// == 1`)
		/// @ingroup error
		template<usize Index>
		auto get() const& noexcept {

			return get_impl<Index>(*this);
		}

	  private:
		template<usize Index, typename T>
		auto get_impl(T&& t) const noexcept {

			static_assert(Index < 2, "Index out of bounds for hyperion::error::AnyError::get");
			if constexpr(Index == 0) {
				return std::forward<T>(t).m_error_code;
			}
			else {
				return std::forward<T>(t).m_message;
			}
		}

		i64 m_error_code = -1;

		std::string m_message;
	};
} // namespace hyperion::error

/// @brief Specialize `std::tuple_size` for `error::AnyError`
/// @ingroup error
template<>
struct std::tuple_size<hyperion::error::AnyError> {
	static constexpr hyperion::usize value = 2;
};

/// @brief Specialize `std::tuple_element<0, T>` for `error::AnyError`
/// @ingroup error
template<>
struct std::tuple_element<0, hyperion::error::AnyError> {
	using type = hyperion::i64;
};

/// @brief Specialize `std::tuple_element<1, T>` for `error::AnyError`
/// @ingroup error
template<>
struct std::tuple_element<1, hyperion::error::AnyError> {
	using type = std::string;
};


#ifdef _MSC_VER
#if _MSC_VER >= 1910
#include <CppCoreCheck/warnings.h>
#pragma warning(disable: ALL_CPPCORECHECK_WARNINGS)
#endif // _MSC_VER >= 1910
#endif // _MSC_VER

#include <gsl/gsl>

#ifdef _MSC_VER
#if _MSC_VER >= 1910
#pragma warning(default: ALL_CPPCORECHECK_WARNINGS)
#endif // _MSC_VER >= 1910
#endif // _MSC_VER


// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#pragma once

#include <gsl/gsl>

namespace _winml {

void LoadSpanFromDisjointBuffers(
    size_t num_buffers,
    std::function<gsl::span<byte>(size_t)> get_buffer,
    gsl::span<byte>& buffer_span);

void StoreSpanIntoDisjointBuffers(
    size_t num_buffers,
    std::function<gsl::span<byte>(size_t)> get_buffer,
    gsl::span<byte>& buffer_span);

} // namespace _winml


#ifndef VERBOSITY_INCLUDE
#define VERBOSITY_INCLUDE

#include <iostream>

#include <gsl/string_span>

#include "config/fleetingOptionsInterface.h"
#include "config/variablesMap.h"
#include "core/task.h"

namespace execHelper {
namespace plugins {
using Verbosity = bool;

const gsl::czstring<> VERBOSITY_KEY = "verbose";

/**
 * \brief Extends the functionality to include the _verbose_ config parameter and processes this parameter, using the --verbose flag
 */
struct VerbosityLong {
    /*! @copydoc JobsLong::getVariables(config::VariablesMap&, const config::FleetingOptionsInterface&)
     */
    static void
    getVariables(config::VariablesMap& variables,
                 const config::FleetingOptionsInterface& options) noexcept;

    /*! @copydoc JobsLong::apply(core::Task&, const config::VariablesMap&)
     */
    inline static void apply(core::Task& task,
                             const config::VariablesMap& variables) noexcept {
        if(*(variables.get<Verbosity>(VERBOSITY_KEY))) {
            task.append("--verbose");
        }
    }
};

/**
 * \brief Extends the functionality to include the _verbose_ config parameter and processes this parameter, using the --debug flag
 */
struct VerbosityDebug {
    /*! @copydoc JobsLong::getVariables(config::VariablesMap&, const config::FleetingOptionsInterface&)
     */
    inline static void
    getVariables(config::VariablesMap& variables,
                 const config::FleetingOptionsInterface& options) noexcept {
        VerbosityLong::getVariables(variables, options);
    }

    /*! @copydoc JobsLong::apply(core::Task&, const config::VariablesMap&)
     */
    inline static void apply(core::Task& task,
                             const config::VariablesMap& variables) noexcept {
        if(*(variables.get<Verbosity>(VERBOSITY_KEY))) {
            task.append("--debug");
        }
    }
};

/**
 * \brief Extends the functionality to include the _verbose_ config parameter and processes this parameter, using the -v flag
 */
struct VerbosityShort {
    /*! @copydoc JobsLong::getVariables(config::VariablesMap&, const config::FleetingOptionsInterface&)
     */
    inline static void
    getVariables(config::VariablesMap& variables,
                 const config::FleetingOptionsInterface& options) noexcept {
        VerbosityLong::getVariables(variables, options);
    }

    /*! @copydoc JobsLong::apply(core::Task&, const config::VariablesMap&)
     */
    inline static void apply(core::Task& task,
                             const config::VariablesMap& variables) noexcept {
        if(*(variables.get<Verbosity>(VERBOSITY_KEY))) {
            task.append("-v");
        }
    }
};
} // namespace plugins
} // namespace execHelper

#endif /* VERBOSITY_INCLUDE */


#ifndef config_e9763ac5_66db_439d_99b9_4c84c1b41e14_h
#define config_e9763ac5_66db_439d_99b9_4c84c1b41e14_h

#include <gslib\config.h>

#ifdef __cplusplus

#define __rathen_begin__    namespace gs { namespace rathen {
#define __rathen_end__      }; };

#endif

/* rathen source postfix & binary postfix */
#define rathen_spf  _t(".rs")
#define rathen_bpf  _t(".rb")

#endif


// Copyright 2021 atframework
// Created by owent on 2016-05-21

#pragma once

#include <string>

#include <gsl/select-gsl.h>
#include <log/log_wrapper.h>

#include "atframe/atapp_config.h"

namespace atapp {
namespace protocol {
class atapp_log;
class atapp_log_category;
class atapp_log_sink;
}  // namespace protocol
}  // namespace atapp

namespace atapp {
class log_sink_maker {
 public:
  using log_reg_t = std::function<util::log::log_wrapper::log_handler_t(
      util::log::log_wrapper &, int32_t, const ::atapp::protocol::atapp_log &,
      const ::atapp::protocol::atapp_log_category &, const ::atapp::protocol::atapp_log_sink &)>;

 private:
  log_sink_maker();
  ~log_sink_maker();

 public:
  static LIBATAPP_MACRO_API gsl::string_view get_file_sink_name();

  static LIBATAPP_MACRO_API log_reg_t get_file_sink_reg();

  static LIBATAPP_MACRO_API gsl::string_view get_stdout_sink_name();

  static LIBATAPP_MACRO_API log_reg_t get_stdout_sink_reg();

  static LIBATAPP_MACRO_API gsl::string_view get_stderr_sink_name();

  static LIBATAPP_MACRO_API log_reg_t get_stderr_sink_reg();

  static LIBATAPP_MACRO_API gsl::string_view get_syslog_sink_name();

  static LIBATAPP_MACRO_API log_reg_t get_syslog_sink_reg();
};
}  // namespace atapp


#pragma once

#include <gsl/gsl>
#include "halley/utils/utils.h"
#include <vector>

namespace Halley {
	class String;
	class Path;

	class FileSystem
	{
	public:
		static bool exists(const Path& p);
		static bool createDir(const Path& p);
		static bool createParentDir(const Path& p);

		static int64_t getLastWriteTime(const Path& p);
		static bool isFile(const Path& p);
		static bool isDirectory(const Path& p);

		static void copyFile(const Path& src, const Path& dst);
		static bool remove(const Path& path);

		static void writeFile(const Path& path, gsl::span<const gsl::byte> data);
		static void writeFile(const Path& path, const Bytes& data);
		static Bytes readFile(const Path& path);

		static std::vector<Path> enumerateDirectory(const Path& path);

		static Path getRelative(const Path& path, const Path& parentPath);
		static Path getAbsolute(const Path& path);

		static size_t fileSize(const Path& path);

		static Path getTemporaryPath();

		static int runCommand(const String& command);
	};
}


/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2017 Couchbase, Inc.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

#pragma once

#include <cJSON.h>
#include <memcached/mcd_util-visibility.h>

#include <gsl/gsl>
#include <string>

namespace cb {
namespace breakpad {
/**
 * What information should breakpad minidumps contain?
 */
enum class Content {
    /**
     * Default content (threads+stack+env+arguments)
     */
    Default
};

/**
 * Settings for Breakpad crash catcher.
 */
struct MCD_UTIL_PUBLIC_API Settings {
    /**
     * Default constructor initialize the object to be in a disabled state
     */
    Settings() = default;

    /**
     * Initialize the Breakpad object from the specified JSON structure
     * which looks like:
     *
     *     {
     *         "enabled" : true,
     *         "minidump_dir" : "/var/crash",
     *         "content" : "default"
     *     }
     *
     * @param json The json to parse
     * @throws std::invalid_argument if the json dosn't look as expected
     */
    explicit Settings(gsl::not_null<const cJSON*> json);

    bool enabled{false};
    std::string minidump_dir;
    Content content{Content::Default};
};

} // namespace breakpad
} // namespace cb

MCD_UTIL_PUBLIC_API
std::string to_string(cb::breakpad::Content content);


/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2018-Present Couchbase, Inc.
 *
 *   Use of this software is governed by the Business Source License included
 *   in the file licenses/BSL-Couchbase.txt.  As of the Change Date specified
 *   in that file, in accordance with the Business Source License, use of this
 *   software will be governed by the Apache License, Version 2.0, included in
 *   the file licenses/APL2.txt.
 */

#pragma once

#include <gsl/gsl-lite.hpp>
#include <nlohmann/json_fwd.hpp>
#include <cstdint>
#include <string>

/**
 * The Event class represents the information needed for a single
 * audit event entry.
 */
class Event {
public:
    Event() = delete;

    /**
     * Construct and initialize a new Event structure based off the
     * provided JSON. See ../README.md for information about the
     * layout of the JSON element.
     *
     * @param entry
     * @throws std::runtime_error for errors accessing the expected
     *                            elements
     */
    explicit Event(const nlohmann::json& json);

    /// The identifier for this entry
    uint32_t id;
    /// The name of the entry
    std::string name;
    /// The full description of the entry
    std::string description;
    /// Set to true if this entry should be handled synchronously
    bool sync;
    /// Set to true if this entry is enabled (or should be dropped)
    bool enabled;
    /// Set to true if the user may enable filtering for the enry
    bool filtering_permitted;
    /// The textual representation of the JSON describing mandatory
    /// fields in the event (NOTE: this is currently not enforced
    /// by the audit daemon)
    std::string mandatory_fields;
    /// The textual representation of the JSON describing the optional
    /// fields in the event (NOTE: this is currently not enforced
    /// by the audit daemon)
    std::string optional_fields;
};


#ifndef EXECUTION_HANDLER_INCLUDE
#define EXECUTION_HANDLER_INCLUDE

#include <map>

#include <gsl/gsl>

#include "executionContent.h"

namespace execHelper {
namespace test {
namespace baseUtils {
class ExecutionHandler {
  public:
    void add(const std::string& key, ExecutionContent&& content) noexcept;

    const ExecutionContent& at(const std::string& key) const noexcept;

  private:
    using ExecutionContentCollection = std::map<std::string, ExecutionContent>;

    /**
     * \brief   Used for handling an execution iteration
     */
    class ExecutionHandlerIterationRAII {
      public:
        explicit ExecutionHandlerIterationRAII(
            gsl::not_null<ExecutionContentCollection*> outputs);
        ~ExecutionHandlerIterationRAII();

        ExecutionHandlerIterationRAII(
            const ExecutionHandlerIterationRAII& other) = default;
        ExecutionHandlerIterationRAII(ExecutionHandlerIterationRAII&& other) =
            default;

        ExecutionHandlerIterationRAII&
        operator=(const ExecutionHandlerIterationRAII& other) = default;
        ExecutionHandlerIterationRAII&
        operator=(ExecutionHandlerIterationRAII&& other) noexcept =
            default; // NOLINT(misc-noexcept-move-constructor)

        const ExecutionContent& at(const std::string& key) const noexcept;

      private:
        gsl::not_null<ExecutionContentCollection*> m_outputs;
    };

    ExecutionContentCollection m_outputs;

  public:
    ExecutionHandlerIterationRAII startIteration() noexcept;
};
} // namespace baseUtils
} // namespace test
} // namespace execHelper

#endif /* EXECUTION_HANDLER_INCLUDE */


/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2018 Couchbase, Inc.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

#pragma once

#include <gsl.h>
#include <nlohmann/json_fwd.hpp>
#include <cstdint>
#include <string>

/**
 * The Event class represents the information needed for a single
 * audit event entry.
 */
class Event {
public:
    Event() = delete;

    /**
     * Construct and initialize a new Event structure based off the
     * provided JSON. See ../README.md for information about the
     * layout of the JSON element.
     *
     * @param entry
     * @throws std::runtime_error for errors accessing the expected
     *                            elements
     */
    explicit Event(const nlohmann::json& json);

    /// The identifier for this entry
    uint32_t id;
    /// The name of the entry
    std::string name;
    /// The full description of the entry
    std::string description;
    /// Set to true if this entry should be handled synchronously
    bool sync;
    /// Set to true if this entry is enabled (or should be dropped)
    bool enabled;
    /// Set to true if the user may enable filtering for the enry
    bool filtering_permitted;
    /// The textual representation of the JSON describing mandatory
    /// fields in the event (NOTE: this is currently not enforced
    /// by the audit daemon)
    std::string mandatory_fields;
    /// The textual representation of the JSON describing the optional
    /// fields in the event (NOTE: this is currently not enforced
    /// by the audit daemon)
    std::string optional_fields;
};


/* -----------------------------------------------------------------------------
 * Copyright 2021 Jonathan Haigh
 * SPDX-License-Identifier: MIT
 * ---------------------------------------------------------------------------*/

#ifndef SQ_INCLUDE_GUARD_system_linux_udev_inl_h_
#define SQ_INCLUDE_GUARD_system_linux_udev_inl_h_

#include "core/errors.h"
#include "core/typeutil.h"

#include <fmt/format.h>
#include <gsl/gsl>

namespace sq::system::linux {

template <typename T> UdevPtr<T>::UdevPtr(SQ_MU std::nullptr_t np) noexcept {}

template <typename T>
UdevPtr<T>::UdevPtr(const UdevPtr &other) noexcept : t_{other.t_.p_} {
  if (t_.p_ != nullptr) {
    t_.add_ref();
  }
}

template <typename T>
UdevPtr<T>::UdevPtr(UdevPtr &&other) noexcept : t_{other.t_.p_} {
  other.t_.p_ = nullptr;
}

// When a raw pointer is first obtained from libudev it already has a reference
// count of 1 so we don't need to adjust it here.
template <typename T> UdevPtr<T>::UdevPtr(RawPtr p) noexcept : t_{p} {
  Expects(p != nullptr);
  Ensures(t_.p_ != nullptr);
}

template <typename T>
UdevPtr<T> &UdevPtr<T>::operator=(const UdevPtr &other) noexcept {
  // Note: must call add_ref before remove_ref to deal with the case where
  // *this == other
  if (other.t_.p_ != nullptr) {
    other.t_.add_ref();
  }
  if (t_.p_ != nullptr) {
    t_.remove_ref();
  }
  t_.p_ = other.t_.p_;
  return *this;
}

template <typename T> UdevPtr<T>::~UdevPtr() noexcept {
  if (t_.p_ != nullptr) {
    t_.remove_ref();
  }
}

template <typename T>
UdevPtr<T> &UdevPtr<T>::operator=(UdevPtr &&other) noexcept {
  std::swap(t_.p_, other.t_.p_);
  return *this;
}

template <typename T> void UdevPtr<T>::reset() noexcept {
  UdevPtr<T>{}.swap(*this);
}

template <typename T> void UdevPtr<T>::swap(UdevPtr &other) noexcept {
  std::swap(t_.p_, other.t_.p_);
}

template <typename T> T *UdevPtr<T>::get() const noexcept {
  if (t_.p_ == nullptr) {
    return nullptr;
  }
  return &t_;
}

template <typename T> T &UdevPtr<T>::operator*() const noexcept {
  Expects(t_.p_ != nullptr);
  return t_;
}

template <typename T> T *UdevPtr<T>::operator->() const noexcept {
  return get();
}

template <typename T> UdevPtr<T>::operator bool() const noexcept {
  return t_.p_ != nullptr;
}

template <typename T>
auto UdevPtr<T>::operator<=>(const UdevPtr<T> &other) const noexcept {
  return std::compare_three_way{}(t_.p_, other.t_.p_);
}

template <typename T>
bool UdevPtr<T>::operator==(const UdevPtr<T> &other) const noexcept {
  return t_.p_ == other.t_.p_;
}

template <typename T>
auto UdevPtr<T>::operator<=>(std::nullptr_t np) const noexcept {
  return std::compare_three_way{}(t_.p_, static_cast<decltype(t_.p_)>(np));
}

template <typename T>
bool UdevPtr<T>::operator==(std::nullptr_t np) const noexcept {
  return t_.p_ == static_cast<decltype(t_.p_)>(np);
}

template <typename U, typename... Args> UdevPtr<U> make_udev(Args &&...args) {
  auto *const p = U::create_new(SQ_FWD(args)...);
  if (p == nullptr) {
    throw UdevError{fmt::format("Failed to create new {}", base_type_name(p))};
  }
  return UdevPtr<U>{p};
}

} // namespace sq::system::linux

#endif // SQ_INCLUDE_GUARD_system_linux_udev_inl_h_


#pragma once
#include "errors.h"
#include "usageinfoformat.h"
#include "detail/config.h"
#include "detail/configmacro.h"
#include "detail/configaccess.h"
#include "detail/flag.h"
#include <gsl/gsl>
#include <iostream>
#include <ostream>
#include <optional>
#include <map>
#include <utility>

namespace cmdlime{

enum class ErrorOutputMode{
    STDOUT,
    STDERR
};

template<typename TConfig>
class ConfigReader{
    struct CommandHelpFlag{
        bool value = false;
        std::string usageInfo;
    };

public:
    ConfigReader(TConfig& cfg,
                 std::string programName,
                 const UsageInfoFormat& usageInfoFormat = {},
                 ErrorOutputMode errorOutputMode = ErrorOutputMode::STDERR)
        : cfg_(cfg)
        , programName_(std::move(programName))
        , usageInfoFormat_(usageInfoFormat)
        , errorOutput_(errorOutputMode == ErrorOutputMode::STDERR ? std::cerr : std::cout)
    {}

    int exitCode() const
    {
        return exitCode_;
    }

    bool read(const std::vector<std::string>& cmdLine)
    {
        addExitFlags();
        if(!processCommandLine(cmdLine))
            return exitOnError(-1);

        if (processFlagsAndExit())
            return exitOnFlag();

        return success();
    }

    bool readCommandLine(int argc, char** argv)
    {
        auto cmdLine = std::vector<std::string>(argv + 1, argv + argc);
        return read(cmdLine);
    }

private:
    void addExitFlags()
    {
        using NameProvider = typename detail::Format<detail::ConfigAccess<TConfig>::format()>::nameProvider;
        auto helpFlag = std::make_unique<detail::Flag>(NameProvider::name("help"),
                                                       std::string{},
                                                       [this]()->bool&{return help_;},
                                                       detail::Flag::Type::Exit);
        helpFlag->info().addDescription("show usage info and exit");
        detail::ConfigAccess<TConfig>{cfg_}.addFlag(std::move(helpFlag));

        if (!cfg_.versionInfo().empty()){
            auto versionFlag = std::make_unique<detail::Flag>(NameProvider::name("version"),
                                                           std::string{},
                                                           [this]()->bool&{return version_;},
                                                           detail::Flag::Type::Exit);
            versionFlag->info().addDescription("show version info and exit");
            detail::ConfigAccess<TConfig>{cfg_}.addFlag(std::move(versionFlag));
        }

        detail::ConfigAccess<TConfig>(cfg_).addHelpFlagToCommands(programName_);
    }

    bool processCommandLine(const std::vector<std::string>& cmdLine)
    {
        try{
            cfg_.read(cmdLine);
        }
        catch(const CommandError& e){
            errorOutput_ << "Command '" + e.commandName() + "' error: " << e.what() << "\n";
            std::cout << e.commandUsageInfo() << std::endl;
            return false;
        }
        catch(const Error& e){
            errorOutput_ << e.what() << "\n";
            std::cout << cfg_.usageInfo(programName_) << std::endl;
            return false;
        }
        return true;
    }

    bool processFlagsAndExit()
    {
        if (help_){
            std::cout << cfg_.usageInfoDetailed(programName_, usageInfoFormat_) << std::endl;
            return true;
        }
        if (version_){
            std::cout << cfg_.versionInfo() << std::endl;
            return true;
        }

        for (auto command :  detail::ConfigAccess<TConfig>{cfg_}.commandList())
            if (checkCommandHelpFlag(command))
                return true;

        return false;
    }

    bool checkCommandHelpFlag(gsl::not_null<detail::ICommand*> command)
    {
        if (command->isHelpFlagSet()){
            std::cout << command->usageInfoDetailed() << std::endl;
            return true;
        }

        for (auto childCommand : command->commandList())
            if (checkCommandHelpFlag(childCommand))
                return true;

        return false;
    }

    bool exitOnFlag()
    {
        exitCode_ = 0;
        return false;
    }

    bool exitOnError(int errorCode)
    {
        exitCode_ = errorCode;
        return false;
    }

    bool success()
    {
        exitCode_ = 0;
        return true;
    }

private:
    TConfig& cfg_;
    std::string programName_;
    UsageInfoFormat usageInfoFormat_;
    std::map<int, CommandHelpFlag> commandHelpFlags_;
    std::ostream& errorOutput_;
    int exitCode_ = 0;
    bool help_ = false;
    bool version_ = false;
}
;
}


#pragma once
#include <wrl/client.h>
#include <d3d11.h>
#include <gsl/span>

namespace vrutil
{
template <typename T> using ComPtr = Microsoft::WRL::ComPtr<T>;
using SharedTexture = std::pair<ComPtr<ID3D11Texture2D>, HANDLE>;

class D3DManager
{
    class D3D11ManagerImpl *m_impl;

public:
    D3DManager();
    ~D3DManager();
    bool Initialize();
    ComPtr<ID3D11Texture2D> CreateStaticTexture(int w, int h, const gsl::span<uint8_t> &bytes);
    SharedTexture CreateSharedStaticTexture(int w, int h, const gsl::span<uint8_t> &bytes);
    void Copy(const ComPtr<ID3D11Texture2D> &src, const ComPtr<ID3D11Texture2D> &dst);
};

} // namespace vrutil


/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef LIBMINIFI_INCLUDE_UTILS_GSL_H_
#define LIBMINIFI_INCLUDE_UTILS_GSL_H_

#include <type_traits>

#include <gsl-lite/gsl-lite.hpp>

namespace org {
namespace apache {
namespace nifi {
namespace minifi {

namespace gsl = ::gsl_lite;

namespace utils {
namespace detail {
template<typename T>
using remove_cvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
}  // namespace detail

template<typename Container, typename T>
Container span_to(gsl::span<T> span) {
  static_assert(std::is_constructible<Container, typename gsl::span<T>::iterator, typename gsl::span<T>::iterator>::value,
      "The destination container must have an iterator (pointer) range constructor");
  return Container(std::begin(span), std::end(span));
}
template<template<typename...> class Container, typename T>
Container<detail::remove_cvref_t<T>> span_to(gsl::span<T> span) {
  static_assert(std::is_constructible<Container<detail::remove_cvref_t<T>>, typename gsl::span<T>::iterator, typename gsl::span<T>::iterator>::value,
      "The destination container must have an iterator (pointer) range constructor");
  return span_to<Container<detail::remove_cvref_t<T>>>(span);
}
}  // namespace utils

}  // namespace minifi
}  // namespace nifi
}  // namespace apache
}  // namespace org

#endif  // LIBMINIFI_INCLUDE_UTILS_GSL_H_


#ifndef XYWEBSERVER_TEST_UTILS_H_
#define XYWEBSERVER_TEST_UTILS_H_

#include <gtest/gtest.h>

#include <gsl/pointers>

#include "runtime/runtime.h"

#define CO_ASSERT_EQ(val1, val2)               \
  ({                                           \
    auto f = [&]() { ASSERT_EQ(val1, val2); }; \
    f();                                       \
  })

constexpr std::chrono::milliseconds time_deviation(7);

class TestRuntimeCtxGuard {
 public:
  TestRuntimeCtxGuard(
      gsl::owner<std::function<xyco::runtime::Future<void>()> *> co_wrapper,
      bool in_runtime);

  TestRuntimeCtxGuard(const TestRuntimeCtxGuard &guard) = delete;

  TestRuntimeCtxGuard(TestRuntimeCtxGuard &&guard) = delete;

  auto operator=(const TestRuntimeCtxGuard &guard)
      -> TestRuntimeCtxGuard & = delete;

  auto operator=(TestRuntimeCtxGuard &&guard) -> TestRuntimeCtxGuard & = delete;

  ~TestRuntimeCtxGuard();

 private:
  gsl::owner<std::function<xyco::runtime::Future<void>()> *> co_wrapper_;
};

class TestRuntimeCtx {
 public:
  // run until co finished
  template <typename Fn>
  static auto co_run(Fn &&co)
      -> void requires(std::is_invocable_r_v<xyco::runtime::Future<void>, Fn>) {
    // co_outer's lifetime is managed by the caller to avoid being destroyed
    // automatically before resumed.

    std::mutex mutex;
    std::unique_lock<std::mutex> lock_guard(mutex);
    std::condition_variable cv;

    auto co_outer = [&]() -> xyco::runtime::Future<void> {
      try {
        co_await co();
        cv.notify_one();
      } catch (std::exception e) {
        auto f = [&]() { ASSERT_NO_THROW(throw e); };
        f();
        cv.notify_one();
      }
    };
    runtime_->spawn(co_outer());
    cv.wait(lock_guard);
  }

  template <typename Fn>
  static auto co_run_no_wait(Fn &&co) -> TestRuntimeCtxGuard
      requires(std::is_invocable_r_v<xyco::runtime::Future<void>, Fn>) {
    auto *co_outer = gsl::owner<std::function<xyco::runtime::Future<void>()> *>(
        new std::function<xyco::runtime::Future<void>()>(
            [=]() -> xyco::runtime::Future<void> { co_await co(); }));

    return {co_outer, true};
  }

  template <typename Fn>
  static auto co_run_without_runtime(Fn &&co) -> TestRuntimeCtxGuard
      requires(std::is_invocable_r_v<xyco::runtime::Future<void>, Fn>) {
    auto *co_outer = gsl::owner<std::function<xyco::runtime::Future<void>()> *>(
        new std::function<xyco::runtime::Future<void>()>(
            [=]() -> xyco::runtime::Future<void> { co_await co(); }));

    return {co_outer, false};
  }

 private : static std::unique_ptr<xyco::runtime::Runtime> runtime_;
};

#endif  // XYWEBSERVER_TEST_UTILS_H_


/*
 * Copyright (c) 2016-2021 lymastee, All rights reserved.
 * Contact: lymastee@hotmail.com
 *
 * This file is part of the gslib project.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#pragma once

#ifndef gsm_129e9ac0_6a88_49a3_8bf1_a95a8edf7da8_h
#define gsm_129e9ac0_6a88_49a3_8bf1_a95a8edf7da8_h

#include <gslib/xml.h>
#include <gslib/json.h>
#include <gslib/uuid.h>
#include <gslib/vdir.h>

/*
 * Make tool introductions.
 * see gsm_help();
 */

__gslib_begin__

enum gsm_project_type
{
    gpt_executable,
    gpt_static_library,
    gpt_dynamic_library,
};

struct gsm_project;
typedef list<string> gsm_str_list;
typedef list<gsm_project> gsm_proj_list;

struct gsm_config
{
    string              source_dir;
    string              target_dir;
    string              spec_compiler;
    bool                is_debug;
};

struct gsm_globals
{
    string              compiler;           /* $compiler */
    string              os_name;            /* $os */
    string              os_version;         /* $os_ver */
    string              source_dir;         /* $src_dir */
    string              target_dir;         /* $tar_dir */
    string              target_name;        /* $tar_name */
    bool                is_debug;           /* $debug */
};

struct gsm_project
{
    string              name;
    uuid                project_id;
    string              output_name;
    gsm_project_type    project_type;
    gsm_str_list        definitions;
    gsm_str_list        libraries;
    string              project_dir;
    string              intermediate_dir;
    string              output_dir;
    gsm_str_list        include_dirs;
    gsm_str_list        library_dirs;
    gsm_str_list        sources;
    json_node_table     ext_sheet;
};

extern void gsm_help(string& str);
extern void gsm_syntax_help(string& str);
extern bool gsm_setup_globals(gsm_globals& globals, const gsm_config& cfgs);
extern bool gsm_prepare_projects(gsm_proj_list& proj_list, vdir& vd, const gsm_globals& globals);
extern bool gsm_generate_projects(vdir& vd, const gsm_globals& globals);
extern bool gsm_finalize_projects(vdir& vd, const gsm_proj_list& projects, const gsm_globals& globals);

__gslib_end__

#endif


// MIT License
//
// Copyright (c) 2020 SunnyCase
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#pragma once
#include "object.h"
#include "utility.h"
#include <chino/io.h>
#include <chino/threading.h>
#include <gsl/gsl-lite.hpp>

namespace chino::io
{
#if defined(_MSC_VER)
#pragma section(".CHDRV$A", long, read) // Begin drivers
#pragma section(".CHDRV$C", long, read) // Drivers
#pragma section(".CHDRV$Z", long, read) // End drivers
#define EXPORT_DRIVER(x) __declspec(allocate(".CHDRV$C")) const ::chino::io::driver *CHINO_CONCAT(_drv_, __COUNTER__) = &x

#pragma section(".CHHDR$A", long, read) // Begin hardware device registrations
#pragma section(".CHHDR$C", long, read) // Hardware device registrations
#pragma section(".CHHDR$Z", long, read) // End hardware device registrations
#define EXPORT_HARDWARE(x) __declspec(allocate(".CHHDR$C")) const ::chino::io::hardware_device_registration *CHINO_CONCAT(_hdr_, __COUNTER__) = &x
#elif defined(__GNUC__)
#define EXPORT_DRIVER(x) __attribute__((unused, section(".chdrv"))) const ::chino::io::driver *CHINO_CONCAT(_drv_, __COUNTER__) = &x
#define EXPORT_HARDWARE(x) __attribute__((unused, section(".chhdr"))) const ::chino::io::hardware_device_registration *CHINO_CONCAT(_hdr_, __COUNTER__) = &x
#else
#error "Unsupported compiler"
#endif

struct driver;
struct device;
struct file;

#define DEFINE_DEV_TYPE(x, v) x = v,
enum class device_type
{
#include "device_types.def"
    COUNT
};
#undef DEFINE_DEV_TYPE

enum class driver_type
{
    hardware,
    console
};

struct hardware_device_registration
{
    const driver &drv;
};

typedef result<void, error_code> (*driver_add_device_t)(const driver &drv, const hardware_device_registration &hdr);
typedef result<void, error_code> (*driver_attach_device_t)(const driver &drv, device &bottom_dev, std::string_view args);
typedef result<file *, error_code> (*driver_open_device_t)(device &dev, std::string_view filename, create_disposition create_disp);
typedef result<void, error_code> (*driver_close_device_t)(file &file);
typedef result<size_t, error_code> (*driver_read_device_t)(file &file, gsl::span<gsl::byte> buffer);
typedef result<void, error_code> (*driver_write_device_t)(file &file, gsl::span<const gsl::byte> buffer);

struct driver_operations
{
    driver_add_device_t add_device;
    driver_attach_device_t attach_device;
    driver_open_device_t open_device;
    driver_close_device_t close_device;
    driver_read_device_t read_device;
    driver_write_device_t write_device;
};

struct driver
{
    driver_type type = driver_type::hardware;
    std::string_view name;
    driver_operations ops;
};

struct device : ob::object
{
    const driver &drv;
    device_type type;
    threading::sched_spinlock syncroot;

    template <class T = uint8_t>
    T &extension() noexcept { return *reinterpret_cast<T *>(reinterpret_cast<uint8_t *>(this) + sizeof(device)); }
};

struct device_extension
{
    device &dev() noexcept { return *reinterpret_cast<device *>(reinterpret_cast<uint8_t *>(this) - sizeof(device)); }
};

struct file : ob::object
{
    device &dev;
    size_t offset;
    threading::sched_spinlock syncroot;

    template <class T = uint8_t>
    T &extension() noexcept { return *reinterpret_cast<T *>(reinterpret_cast<uint8_t *>(this) + sizeof(file)); }
};

struct file_extension
{
    io::file &file() noexcept { return *reinterpret_cast<io::file *>(reinterpret_cast<uint8_t *>(this) - sizeof(device)); }
};

result<device *, error_code> create_device(const driver &drv, device_type type, size_t extension_size) noexcept;
result<device *, error_code> create_device(std::string_view name, const driver &drv, device_type type, size_t extension_size) noexcept;
result<file *, error_code> create_file(device &dev, size_t extension_size) noexcept;

result<file *, error_code> open_file(device &dev, access_mask access, std::string_view filename, create_disposition create_disp = create_disposition::open_existing) noexcept;
result<size_t, error_code> read_file(file &file, gsl::span<gsl::byte> buffer) noexcept;
result<void, error_code> write_file(file &file, gsl::span<const gsl::byte> buffer) noexcept;
result<void, error_code> close_file(file &file) noexcept;
}


#ifndef LIC_METADATA_DEFINITION
#define LIC_METADATA_DEFINITION

#include <gsl/gsl>

#include "format/ClrMetadataFormat.h"

namespace lic
{

class Assembly;

class Metadata
{
public:
    Metadata(Assembly& assembly, MetadataTable table, size_t rid, gsl::byte* row);
    ~Metadata();

protected:
    Assembly& assembly;
    MetadataTable table;
    size_t rid;
    gsl::byte* row;
};

}

#endif // !LIC_METADATA_DEFINITION


#ifndef ENVIRONMENT_INCLUDE
#define ENVIRONMENT_INCLUDE

#include <map>
#include <string>
#include <vector>

#include <gsl/string_span>

namespace execHelper {
namespace config {
using EnvArg = std::string;
using EnvArgs = std::vector<EnvArg>;

using EnvironmentCollection = std::map<std::string, EnvArg>;
using EnvironmentValue = std::pair<std::string, EnvArg>;

static const gsl::czstring<> ENVIRONMENT_KEY = "environment";

} // namespace config
} // namespace execHelper

#endif /* ENVIRONMENT_INCLUDE */


#ifndef STATEMENT_INCLUDE
#define STATEMENT_INCLUDE

#include <string>

#include <gsl/gsl>

#include "executionContent.h"
#include "yaml.h"

namespace execHelper {
namespace test {
namespace baseUtils {
using StatementKey = std::string;
using StatementCollection = ExecutionContent::ConfigCommand;

class Statement {
  public:
    virtual ~Statement() = default;

    virtual StatementKey getKey() const noexcept = 0;
    virtual void write(gsl::not_null<YamlWriter*> yaml,
                       const std::string& command) const noexcept = 0;

    virtual inline unsigned int getNumberOfExecutions() const noexcept {
        return m_execution.getNumberOfExecutions();
    }

    virtual inline void resetExecutions() noexcept { m_execution.clear(); }

  protected:
    Statement(ReturnCode returnCode) noexcept : m_execution(returnCode) {}

    ExecutionContent m_execution;
};
} // namespace baseUtils
} // namespace test
} // namespace execHelper

#endif /* STATEMENT_INCLUDE */


#pragma once

#include <gsl/gsl>

#include <vector>
#include <memory>
#include <mutex>

struct AVFrame;

namespace video_streamer
{

class StreamSession;
class FrameEncoder;

class GroupStreamSession
{
public:
    explicit GroupStreamSession(std::shared_ptr<FrameEncoder> frameEncoder);

    void addStream(std::unique_ptr<StreamSession> streamSession);
    void pushFrame(gsl::not_null<const AVFrame*> frame);

private:
    std::shared_ptr<FrameEncoder> m_frameEncoder;
    std::vector<std::unique_ptr<StreamSession>> m_streamSession;
    mutable std::mutex m_mtx;
};

} // video_streamer


/*
 * Copyright (c) 2016-2021 lymastee, All rights reserved.
 * Contact: lymastee@hotmail.com
 *
 * This file is part of the gslib project.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#pragma once

#ifndef applicationwin32_3971e4cb_1be6_4066_b7ea_da679d40c987_h
#define applicationwin32_3971e4cb_1be6_4066_b7ea_da679d40c987_h

#include <gslib/string.h>
#include <gslib/std.h>
#include <ariel/application.h>
#include <windows.h>

#undef min
#undef max

__ariel_begin__

typedef LRESULT(__stdcall *fnwndproc)(HWND, UINT, WPARAM, LPARAM);
typedef list<string> arg_list;

extern void set_execute_path_as_directory();
extern void init_application_environment(app_env& env);
extern void init_application_environment(app_env& env, HINSTANCE hinst, HINSTANCE hprevinst, const gchar* argv[], int argc);

struct app_data
{
    HINSTANCE           hinst = nullptr;
    HWND                hwnd = nullptr;
    fnwndproc           wndproc = nullptr;
    arg_list            arglist;

public:
    bool install(const app_config& cfg, const app_env& env);
    int run();
};

struct app_env
{
    HINSTANCE           hinst = nullptr;
    HINSTANCE           hprevinst = nullptr;
    arg_list            arglist;

public:
    void init(HINSTANCE hinst, HINSTANCE hprevinst, const gchar* argv[], int argc) { init_application_environment(*this, hinst, hprevinst, argv, argc); }
};

__ariel_end__

#endif


#ifndef VKST_PLAT_LOG_H
#define VKST_PLAT_LOG_H

#include <plat/core.h>
#include <plat/filesystem.h>
#include <gsl.h>
#include <string>

namespace plat {

// Initialize logging with output to a given path.
// Must be called before logging output will occur.
void init_logging(plat::filesystem::path logfile, std::error_code& ec) noexcept;

enum class log_severities : uint8_t {
  trace = 1,
  debug,
  info,
  warn,
  error,
  fatal,
  none
};

inline constexpr gsl::czstring to_string(log_severities severity) noexcept {
  switch(severity) {
  case log_severities::trace: return "TRACE";
  case log_severities::debug: return "DEBUG";
  case log_severities::info: return "INFO";
  case log_severities::warn: return "WARN";
  case log_severities::error: return "ERROR";
  case log_severities::fatal: return "FATAL";
  case log_severities::none: return "NONE";
  }
  PLAT_MARK_UNREACHABLE;
}

void log(log_severities severity, gsl::czstring fmt, ...) noexcept;

#define LOG_TRACE(...) ::plat::log(::plat::log_severities::trace, __VA_ARGS__)
#define LOG_DEBUG(...) ::plat::log(::plat::log_severities::debug, __VA_ARGS__)
#define LOG_INFO(...) ::plat::log(::plat::log_severities::info, __VA_ARGS__)
#define LOG_WARN(...) ::plat::log(::plat::log_severities::warn, __VA_ARGS__)
#define LOG_ERROR(...) ::plat::log(::plat::log_severities::error, __VA_ARGS__)
#define LOG_FATAL(...) ::plat::log(::plat::log_severities::fatal, __VA_ARGS__)

#define LOG_ENTER                                                              \
  ::plat::log(::plat::log_severities::trace, "enter: %s (%s:%d)", __func__,    \
              __FILE__, __LINE__)
#define LOG_LEAVE                                                              \
  ::plat::log(::plat::log_severities::trace, "leave: %s (%s:%d)", __func__,    \
              __FILE__, __LINE__)

} // namespace plat

#endif // VKST_PLAT_LOG_H


#ifndef LIC_TYPE_DEFINITION
#define LIC_TYPE_DEFINITION

#include <gsl/gsl>

#include "Metadata.h"

namespace lic
{

class MethodDefinition;

class TypeDefinition : Metadata
{
public:
    TypeDefinition(Assembly& assembly, MetadataTable table, size_t rid, gsl::byte* row);
    ~TypeDefinition();

    const char* Name() const;
    const char* Namespace() const;
    const gsl::span<MethodDefinition> Methods();

private:
    size_t FirstMethodRid();
};

}

#endif // !LIC_TYPE_DEFINITION


#pragma once

#include "Cesium3DTiles/Library.h"
#include "Cesium3DTiles/RasterOverlay.h"
#include "Cesium3DTiles/RasterOverlayTileProvider.h"
#include <gsl/span>
#include <memory>
#include <vector>

namespace Cesium3DTiles {

class Tileset;

/**
 * @brief A collection of {@link RasterOverlay} instances that are associated
 * with a {@link Tileset}.
 *
 * The raster overlay instances may be added to the raster overlay collection
 * of a tileset that is returned with {@link Tileset::getOverlays}. When the
 * tileset is loaded, one {@link RasterOverlayTileProvider} will be created
 * for each raster overlay that had been added. The raster overlay tile provider
 * instances will be passed to the {@link RasterOverlayTile} instances that
 * they create when the tiles are updated.
 */
class CESIUM3DTILES_API RasterOverlayCollection final {
public:
  /**
   * @brief Creates a new instance.
   *
   * @param tileset The tileset to which this instance belongs
   */
  RasterOverlayCollection(Tileset& tileset) noexcept;

  ~RasterOverlayCollection();

  /**
   * @brief Adds the given {@link RasterOverlay} to this collection.
   *
   * @param pOverlay The pointer to the overlay. This may not be `nullptr`.
   */
  void add(std::unique_ptr<RasterOverlay>&& pOverlay);

  /**
   * @brief Remove the given {@link RasterOverlay} from this collection.
   */
  void remove(RasterOverlay* pOverlay) noexcept;

  /**
   * @brief A constant iterator for {@link RasterOverlay} instances.
   */
  typedef std::vector<std::unique_ptr<RasterOverlay>>::const_iterator
      const_iterator;

  /**
   * @brief Returns an iterator at the beginning of this collection.
   */
  const_iterator begin() const noexcept { return this->_overlays.begin(); }

  /**
   * @brief Returns an iterator at the end of this collection.
   */
  const_iterator end() const noexcept { return this->_overlays.end(); }

  /**
   * @brief Gets the number of overlays in the collection.
   */
  size_t size() const noexcept { return this->_overlays.size(); }

private:
  Tileset* _pTileset;
  std::vector<std::unique_ptr<RasterOverlay>> _overlays;
};

} // namespace Cesium3DTiles