text:
//
// Copyright 2021 Autodesk
//
// 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.
//

#include "pythonObjectRegistry.h"
#include "wrapSparseValueWriter.h"

#include <mayaUsd/fileio/primWriter.h>
#include <mayaUsd/fileio/primWriterRegistry.h>
#include <mayaUsd/fileio/registryHelper.h>
#include <mayaUsd/fileio/shaderWriter.h>
#include <mayaUsd/fileio/shaderWriterRegistry.h>
#include <mayaUsd/fileio/shading/symmetricShaderWriter.h>

#include <pxr/base/tf/pyContainerConversions.h>
#include <pxr/base/tf/pyEnum.h>
#include <pxr/base/tf/pyPolymorphic.h>
#include <pxr/base/tf/pyResultConversions.h>

#include <boost/python/class.hpp>
#include <boost/python/def.hpp>
#include <boost/python/make_constructor.hpp>
#include <boost/python/return_internal_reference.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/wrapper.hpp>

PXR_NAMESPACE_USING_DIRECTIVE

//----------------------------------------------------------------------------------------------------------------------
/// \brief  boost python binding for the UsdMayaPrimWriter
//----------------------------------------------------------------------------------------------------------------------
template <typename T = UsdMayaPrimWriter>
class PrimWriterWrapper
    : public T
    , public TfPyPolymorphic<UsdMayaPrimWriter>
{
public:
    typedef PrimWriterWrapper This;
    typedef T                 base_t;

    PrimWriterWrapper(
        const MFnDependencyNode& depNodeFn,
        const SdfPath&           usdPath,
        UsdMayaWriteJobContext&  jobCtx)
        : T(depNodeFn, usdPath, jobCtx)
    {
    }

    static std::shared_ptr<This> New(uintptr_t createdWrapper)
    {
        return *((std::shared_ptr<This>*)createdWrapper);
    }

    virtual ~PrimWriterWrapper() = default;

    const UsdStage& GetUsdStage() const { return *get_pointer(base_t::GetUsdStage()); }

    // This is the pattern inspired from USD/pxr/base/tf/wrapTestTfPython.cpp
    // It would have been simpler to call 'this->CallVirtual<>("Write",
    // &base_t::default_Write)(usdTime);' But it is not allowed Instead of having to create a
    // function 'default_Write(...)' to call the base class when there is no Python implementation.
    void default_Write(const UsdTimeCode& usdTime) { base_t::Write(usdTime); }
    void Write(const UsdTimeCode& usdTime) override
    {
        this->template CallVirtual<>("Write", &This::default_Write)(usdTime);
    }

    void default_PostExport() { base_t::PostExport(); }
    void PostExport() override
    {
        this->template CallVirtual<>("PostExport", &This::default_PostExport)();
    }

    bool default_ExportsGprims() const { return base_t::ExportsGprims(); }
    bool ExportsGprims() const override
    {
        return this->template CallVirtual<bool>("ExportsGprims", &This::default_ExportsGprims)();
    }

    bool default_ShouldPruneChildren() const { return base_t::ShouldPruneChildren(); };
    bool ShouldPruneChildren() const override
    {
        return this->template CallVirtual<bool>(
            "ShouldPruneChildren", &This::default_ShouldPruneChildren)();
    }

    bool default__HasAnimCurves() const { return base_t::_HasAnimCurves(); };
    bool _HasAnimCurves() const override
    {
        return this->template CallVirtual<bool>("_HasAnimCurves", &This::default__HasAnimCurves)();
    }

    const SdfPathVector& default_GetModelPaths() const { return base_t::GetModelPaths(); }
    const SdfPathVector& GetModelPaths() const override
    {
        if (Override o = GetOverride("GetModelPaths")) {
            auto res = std::function<boost::python::object()>(TfPyCall<boost::python::object>(o))();
            if (res) {
                const_cast<SdfPathVector*>(&_modelPaths)->clear();
                TfPyLock pyLock;

                boost::python::list keys(res);
                for (int i = 0; i < len(keys); ++i) {
                    boost::python::extract<SdfPath> extractedKey(keys[i]);
                    if (!extractedKey.check()) {
                        TF_CODING_ERROR(
                            "PrimWriterWrapper.GetModelPaths: SdfPath key expected, not "
                            "found!");
                        return _modelPaths;
                    }

                    SdfPath path = extractedKey;
                    const_cast<SdfPathVector*>(&_modelPaths)->push_back(path);
                }
                return _modelPaths;
            }
        }
        return This::default_GetModelPaths();
    }

    const UsdMayaUtil::MDagPathMap<SdfPath>& default_GetDagToUsdPathMapping() const
    {
        return base_t::GetDagToUsdPathMapping();
    }
    const UsdMayaUtil::MDagPathMap<SdfPath>& GetDagToUsdPathMapping() const override
    {
        if (Override o = GetOverride("GetDagToUsdPathMapping")) {
            auto res = std::function<boost::python::object()>(TfPyCall<boost::python::object>(o))();
            if (res) {
                const_cast<UsdMayaUtil::MDagPathMap<SdfPath>*>(&_dagPathMap)->clear();
                TfPyLock pyLock;

                boost::python::list tuples(res);
                for (int i = 0; i < len(tuples); ++i) {
                    boost::python::tuple t(tuples[i]);
                    if (boost::python::len(t) != 2) {
                        TF_CODING_ERROR("PrimWriterWrapper.GetDagToUsdPathMapping: list<tuples> "
                                        "key expected, not "
                                        "found!");
                        return _dagPathMap;
                    }
                    boost::python::extract<MDagPath> extractedDagPath(t[0]);
                    if (!extractedDagPath.check()) {
                        TF_CODING_ERROR(
                            "PrimWriterWrapper.GetDagToUsdPathMapping: MDagPath key expected, not "
                            "found!");
                        return _dagPathMap;
                    }
                    boost::python::extract<SdfPath> extractedSdfPath(t[1]);
                    if (!extractedSdfPath.check()) {
                        TF_CODING_ERROR(
                            "PrimWriterWrapper.GetDagToUsdPathMapping: SdfPath key expected, not "
                            "found!");
                        return _dagPathMap;
                    }

                    MDagPath dagPath = extractedDagPath;
                    SdfPath  path = extractedSdfPath;
                    const_cast<UsdMayaUtil::MDagPathMap<SdfPath>*>(&_dagPathMap)
                        ->
                        operator[](dagPath)
                        = path;
                }
                return _dagPathMap;
            }
        }
        return This::default_GetDagToUsdPathMapping();
    }

    //---------------------------------------------------------------------------------------------
    /// \brief  wraps a factory function that allows registering an updated Python class
    //---------------------------------------------------------------------------------------------
    class FactoryFnWrapper : public UsdMayaPythonObjectRegistry
    {
    public:
        // Instances of this class act as "function objects" that are fully compatible with the
        // std::function requested by UsdMayaSchemaApiAdaptorRegistry::Register. These will create
        // python wrappers based on the latest class registered.
        UsdMayaPrimWriterSharedPtr operator()(
            const MFnDependencyNode& depNodeFn,
            const SdfPath&           usdPath,
            UsdMayaWriteJobContext&  jobCtx)
        {
            boost::python::object pyClass = GetPythonObject(_classIndex);
            if (!pyClass) {
                // Prototype was unregistered
                return nullptr;
            }
            auto                  sptr = std::make_shared<This>(depNodeFn, usdPath, jobCtx);
            TfPyLock              pyLock;
            boost::python::object instance = pyClass((uintptr_t)&sptr);
            boost::python::incref(instance.ptr());
            initialize_wrapper(instance.ptr(), sptr.get());
            return sptr;
        }

        // Create a new wrapper for a Python class that is seen for the first time for a given
        // purpose. If we already have a registration for this purpose: update the class to
        // allow the previously issued factory function to use it.
        static UsdMayaPrimWriterRegistry::WriterFactoryFn
        Register(boost::python::object cl, const std::string& mayaTypeName)
        {
            size_t classIndex = RegisterPythonObject(cl, GetKey(cl, mayaTypeName));
            if (classIndex != UsdMayaPythonObjectRegistry::UPDATED) {
                // Return a new factory function:
                return FactoryFnWrapper { classIndex };
            } else {
                // We already registered a factory function for this purpose:
                return nullptr;
            }
        }

        // Unregister a class for a given purpose. This will cause the associated factory
        // function to stop producing this Python class.
        static void Unregister(boost::python::object cl, const std::string& mayaTypeName)
        {
            UnregisterPythonObject(cl, GetKey(cl, mayaTypeName));
        }

    private:
        // Function object constructor. Requires only the index of the Python class to use.
        FactoryFnWrapper(size_t classIndex)
            : _classIndex(classIndex) {};

        size_t _classIndex;

        // Generates a unique key based on the name of the class, along with the class
        // purpose:
        static std::string GetKey(boost::python::object cl, const std::string& mayaTypeName)
        {
            return ClassName(cl) + "," + mayaTypeName + "," + ",PrimWriter";
        }
    };

    static void Register(boost::python::object cl, const std::string& mayaTypeName)
    {
        UsdMayaPrimWriterRegistry::WriterFactoryFn fn
            = FactoryFnWrapper::Register(cl, mayaTypeName);
        if (fn) {
            UsdMayaPrimWriterRegistry::Register(mayaTypeName, fn, true);
        }
    }

    static void Unregister(boost::python::object cl, const std::string& mayaTypeName)
    {
        FactoryFnWrapper::Unregister(cl, mayaTypeName);
    }

private:
    SdfPathVector                     _modelPaths;
    UsdMayaUtil::MDagPathMap<SdfPath> _dagPathMap;
};

//----------------------------------------------------------------------------------------------------------------------
/// \brief  boost python binding for the UsdMayaShaderWriter
//----------------------------------------------------------------------------------------------------------------------
class ShaderWriterWrapper : public PrimWriterWrapper<UsdMayaShaderWriter>
{
public:
    typedef ShaderWriterWrapper This;
    typedef UsdMayaShaderWriter base_t;

    ShaderWriterWrapper(
        const MFnDependencyNode& depNodeFn,
        const SdfPath&           usdPath,
        UsdMayaWriteJobContext&  jobCtx)
        : PrimWriterWrapper<UsdMayaShaderWriter>(depNodeFn, usdPath, jobCtx)
    {
    }

    static std::shared_ptr<This> New(uintptr_t createdWrapper)
    {
        return *((std::shared_ptr<This>*)createdWrapper);
    }

    virtual ~ShaderWriterWrapper() { }

    TfToken default_GetShadingAttributeNameForMayaAttrName(const TfToken& mayaAttrName)
    {
        return base_t::GetShadingAttributeNameForMayaAttrName(mayaAttrName);
    }
    TfToken GetShadingAttributeNameForMayaAttrName(const TfToken& mayaAttrName) override
    {
        return this->CallVirtual<TfToken>(
            "GetShadingAttributeNameForMayaAttrName",
            &This::default_GetShadingAttributeNameForMayaAttrName)(mayaAttrName);
    }

    UsdAttribute default_GetShadingAttributeForMayaAttrName(
        const TfToken&          mayaAttrName,
        const SdfValueTypeName& typeName)
    {
        return base_t::GetShadingAttributeForMayaAttrName(mayaAttrName, typeName);
    }
    UsdAttribute GetShadingAttributeForMayaAttrName(
        const TfToken&          mayaAttrName,
        const SdfValueTypeName& typeName) override
    {
        return this->CallVirtual<UsdAttribute>(
            "GetShadingAttributeForMayaAttrName",
            &This::default_GetShadingAttributeForMayaAttrName)(mayaAttrName, typeName);
    }

    //---------------------------------------------------------------------------------------------
    /// \brief  wraps a factory function that allows registering an updated Python class
    //---------------------------------------------------------------------------------------------
    class FactoryFnWrapper : public UsdMayaPythonObjectRegistry
    {
    public:
        // Instances of this class act as "function objects" that are fully compatible with the
        // std::function requested by UsdMayaSchemaApiAdaptorRegistry::Register. These will create
        // python wrappers based on the latest class registered.
        UsdMayaShaderWriterSharedPtr operator()(
            const MFnDependencyNode& depNodeFn,
            const SdfPath&           usdPath,
            UsdMayaWriteJobContext&  jobCtx)
        {
            boost::python::object pyClass = GetPythonObject(_classIndex);
            auto                  sptr = std::make_shared<This>(depNodeFn, usdPath, jobCtx);
            TfPyLock              pyLock;
            boost::python::object instance = pyClass((uintptr_t)&sptr);
            boost::python::incref(instance.ptr());
            initialize_wrapper(instance.ptr(), sptr.get());
            return sptr;
        }

        // We can have multiple function objects, this one apapts the CanImport function:
        UsdMayaShaderWriter::ContextSupport operator()(const UsdMayaJobExportArgs& exportArgs)
        {
            boost::python::object pyClass = GetPythonObject(_classIndex);
            if (!pyClass) {
                // Prototype was unregistered
                return UsdMayaShaderWriter::ContextSupport::Unsupported;
            }
            TfPyLock              pyLock;
            boost::python::object CanExport = pyClass.attr("CanExport");
            PyObject*             callable = CanExport.ptr();
            auto                  res = boost::python::call<int>(callable, exportArgs);
            return UsdMayaShaderWriter::ContextSupport(res);
        }

        // Create a new wrapper for a Python class that is seen for the first time for a given
        // purpose. If we already have a registration for this purpose: update the class to
        // allow the previously issued factory function to use it.
        static FactoryFnWrapper
        Register(boost::python::object cl, const std::string& usdShaderId, bool& updated)
        {
            size_t classIndex = RegisterPythonObject(cl, GetKey(cl, usdShaderId));
            updated = classIndex == UsdMayaPythonObjectRegistry::UPDATED;
            // Return a new factory function:
            return FactoryFnWrapper { classIndex };
        }

        // Unregister a class for a given purpose. This will cause the associated factory
        // function to stop producing this Python class.
        static void Unregister(boost::python::object cl, const std::string& usdShaderId)
        {
            UnregisterPythonObject(cl, GetKey(cl, usdShaderId));
        }

    private:
        // Function object constructor. Requires only the index of the Python class to use.
        FactoryFnWrapper(size_t classIndex)
            : _classIndex(classIndex) {};

        size_t _classIndex;

        // Generates a unique key based on the name of the class, along with the class
        // purpose:
        static std::string GetKey(boost::python::object cl, const std::string& usdShaderId)
        {
            return ClassName(cl) + "," + usdShaderId + "," + ",ShaderWriter";
        }
    };

    static void Register(boost::python::object cl, const TfToken& usdShaderId)
    {
        bool             updated = false;
        FactoryFnWrapper fn = FactoryFnWrapper::Register(cl, usdShaderId, updated);
        if (!updated) {
            UsdMayaShaderWriterRegistry::Register(usdShaderId, fn, fn, true);
        }
    }

    static void Unregister(boost::python::object cl, const TfToken& usdShaderId)
    {
        FactoryFnWrapper::Unregister(cl, usdShaderId);
    }

    static void RegisterSymmetric(
        boost::python::object cl,
        const TfToken&        mayaNodeTypeName,
        const TfToken&        usdShaderId,
        const TfToken&        materialConversionName)
    {
        UsdMayaSymmetricShaderWriter::RegisterWriter(
            mayaNodeTypeName, usdShaderId, materialConversionName, true);
    }
};

namespace {

boost::python::object get_allChaserArgs(UsdMayaJobExportArgs& self)
{
    boost::python::dict allChaserArgs;
    for (auto&& perChaser : self.allChaserArgs) {
        auto perChaserDict = boost::python::dict();
        for (auto&& perItem : perChaser.second) {
            perChaserDict[perItem.first] = perItem.second;
        }
        allChaserArgs[perChaser.first] = perChaserDict;
    }
    return boost::python::object(allChaserArgs);
}

// This class is used to expose protected members of UsdMayaPrimWriter to Python
class PrimWriterAllowProtected : public UsdMayaPrimWriter
{
    typedef UsdMayaPrimWriter base_t;

public:
    void _SetUsdPrim(const UsdPrim& usdPrim) { base_t::_SetUsdPrim(usdPrim); }
    const UsdMayaJobExportArgs& _GetExportArgs() const { return base_t::_GetExportArgs(); }
    UsdUtilsSparseValueWriter*  _GetSparseValueWriter() { return base_t::_GetSparseValueWriter(); }
};

void unprotect_SetUsdPrim(UsdMayaPrimWriter& pw, const UsdPrim& prim)
{
    reinterpret_cast<PrimWriterAllowProtected&>(pw)._SetUsdPrim(prim);
}
const UsdMayaJobExportArgs& unprotect_GetExportArgs(UsdMayaPrimWriter& pw)
{
    return reinterpret_cast<PrimWriterAllowProtected&>(pw)._GetExportArgs();
}
MayaUsdLibSparseValueWriter unprotect_GetSparseValueWriter(UsdMayaPrimWriter& pw)
{
    return MayaUsdLibSparseValueWriter(
        reinterpret_cast<PrimWriterAllowProtected&>(pw)._GetSparseValueWriter());
}

} // namespace
//----------------------------------------------------------------------------------------------------------------------
void wrapJobExportArgs()
{
    using namespace boost::python;

    class_<UsdMayaJobExportArgs>("JobExportArgs", no_init)
        .add_property("allChaserArgs", ::get_allChaserArgs)
        .add_property(
            "allMaterialConversions",
            make_getter(
                &UsdMayaJobExportArgs::allMaterialConversions,
                return_value_policy<TfPySequenceToSet>()))
        .add_property(
            "chaserNames",
            make_getter(
                &UsdMayaJobExportArgs::chaserNames, return_value_policy<TfPySequenceToSet>()))
        .add_property(
            "compatibility",
            make_getter(
                &UsdMayaJobExportArgs::compatibility, return_value_policy<return_by_value>()))
        .add_property(
            "convertMaterialsTo",
            make_getter(
                &UsdMayaJobExportArgs::convertMaterialsTo, return_value_policy<return_by_value>()))
        //.add_property("dagPaths", requires exporting UsdMayaUtil::MDagPathSet)
        .add_property(
            "defaultMeshScheme",
            make_getter(
                &UsdMayaJobExportArgs::defaultMeshScheme, return_value_policy<return_by_value>()))
        .add_property(
            "defaultUSDFormat",
            make_getter(
                &UsdMayaJobExportArgs::defaultUSDFormat, return_value_policy<return_by_value>()))
        .def_readonly("eulerFilter", &UsdMayaJobExportArgs::eulerFilter)
        .def_readonly("excludeInvisible", &UsdMayaJobExportArgs::excludeInvisible)
        .def_readonly("exportBlendShapes", &UsdMayaJobExportArgs::exportBlendShapes)
        .def_readonly(
            "exportCollectionBasedBindings", &UsdMayaJobExportArgs::exportCollectionBasedBindings)
        .def_readonly("exportColorSets", &UsdMayaJobExportArgs::exportColorSets)
        .def_readonly("exportComponentTags", &UsdMayaJobExportArgs::exportComponentTags)
        .def_readonly("exportDefaultCameras", &UsdMayaJobExportArgs::exportDefaultCameras)
        .def_readonly("exportDisplayColor", &UsdMayaJobExportArgs::exportDisplayColor)
        .def_readonly("exportInstances", &UsdMayaJobExportArgs::exportInstances)
        .def_readonly("exportMaterialCollections", &UsdMayaJobExportArgs::exportMaterialCollections)
        .def_readonly("exportMeshUVs", &UsdMayaJobExportArgs::exportMeshUVs)
        .def_readonly("exportNurbsExplicitUV", &UsdMayaJobExportArgs::exportNurbsExplicitUV)
        .def_readonly("exportReferenceObjects", &UsdMayaJobExportArgs::exportReferenceObjects)
        .def_readonly("exportRefsAsInstanceable", &UsdMayaJobExportArgs::exportRefsAsInstanceable)
        .add_property(
            "exportSkels",
            make_getter(&UsdMayaJobExportArgs::exportSkels, return_value_policy<return_by_value>()))
        .add_property(
            "exportSkin",
            make_getter(&UsdMayaJobExportArgs::exportSkin, return_value_policy<return_by_value>()))
        .def_readonly("exportVisibility", &UsdMayaJobExportArgs::exportVisibility)
        .def_readonly("file", &UsdMayaJobExportArgs::file)
        .add_property(
            "filteredTypeIds",
            make_getter(
                &UsdMayaJobExportArgs::filteredTypeIds, return_value_policy<TfPySequenceToSet>()))
        .add_property(
            "geomSidedness",
            make_getter(
                &UsdMayaJobExportArgs::geomSidedness, return_value_policy<return_by_value>()))
        .def_readonly("ignoreWarnings", &UsdMayaJobExportArgs::ignoreWarnings)
        .add_property(
            "includeAPINames",
            make_getter(
                &UsdMayaJobExportArgs::includeAPINames, return_value_policy<TfPySequenceToSet>()))
        .add_property(
            "jobContextNames",
            make_getter(
                &UsdMayaJobExportArgs::jobContextNames, return_value_policy<TfPySequenceToSet>()))
        .add_property(
            "materialCollectionsPath",
            make_getter(
                &UsdMayaJobExportArgs::materialCollectionsPath,
                return_value_policy<return_by_value>()))
        .add_property(
            "materialsScopeName",
            make_getter(
                &UsdMayaJobExportArgs::materialsScopeName, return_value_policy<return_by_value>()))
        .def_readonly("melPerFrameCallback", &UsdMayaJobExportArgs::melPerFrameCallback)
        .def_readonly("melPostCallback", &UsdMayaJobExportArgs::melPostCallback)
        .def_readonly("mergeTransformAndShape", &UsdMayaJobExportArgs::mergeTransformAndShape)
        .def_readonly("normalizeNurbs", &UsdMayaJobExportArgs::normalizeNurbs)
        .add_property(
            "parentScope",
            make_getter(&UsdMayaJobExportArgs::parentScope, return_value_policy<return_by_value>()))
        .def_readonly("pythonPerFrameCallback", &UsdMayaJobExportArgs::pythonPerFrameCallback)
        .def_readonly("pythonPostCallback", &UsdMayaJobExportArgs::pythonPostCallback)
        .add_property(
            "renderLayerMode",
            make_getter(
                &UsdMayaJobExportArgs::renderLayerMode, return_value_policy<return_by_value>()))
        .add_property(
            "rootKind",
            make_getter(&UsdMayaJobExportArgs::rootKind, return_value_policy<return_by_value>()))
        .add_property(
            "rootMapFunction",
            make_getter(
                &UsdMayaJobExportArgs::rootMapFunction, return_value_policy<return_by_value>()))
        .add_property(
            "shadingMode",
            make_getter(&UsdMayaJobExportArgs::shadingMode, return_value_policy<return_by_value>()))
        .def_readonly("staticSingleSample", &UsdMayaJobExportArgs::staticSingleSample)
        .def_readonly("stripNamespaces", &UsdMayaJobExportArgs::stripNamespaces)
        .add_property(
            "timeSamples",
            make_getter(&UsdMayaJobExportArgs::timeSamples, return_value_policy<return_by_value>()))
        .add_property(
            "usdModelRootOverridePath",
            make_getter(
                &UsdMayaJobExportArgs::usdModelRootOverridePath,
                return_value_policy<return_by_value>()))
        .def_readonly("verbose", &UsdMayaJobExportArgs::verbose)
        .def("GetResolvedFileName", &UsdMayaJobExportArgs::GetResolvedFileName);
}

void wrapPrimWriter()
{
    boost::python::class_<PrimWriterWrapper<>, boost::noncopyable>(
        "PrimWriter", boost::python::no_init)
        .def("__init__", make_constructor(&PrimWriterWrapper<>::New))
        .def(
            "PostExport",
            &PrimWriterWrapper<>::PostExport,
            &PrimWriterWrapper<>::default_PostExport)
        .def("Write", &PrimWriterWrapper<>::Write, &PrimWriterWrapper<>::default_Write)

        .def("GetExportVisibility", &PrimWriterWrapper<>::GetExportVisibility)
        .def("SetExportVisibility", &PrimWriterWrapper<>::SetExportVisibility)
        .def(
            "GetMayaObject",
            &PrimWriterWrapper<>::GetMayaObject,
            boost::python::return_value_policy<boost::python::return_by_value>())
        .def(
            "GetUsdPrim",
            &PrimWriterWrapper<>::GetUsdPrim,
            boost::python::return_internal_reference<>())
        .def("_SetUsdPrim", &::unprotect_SetUsdPrim)
        .def(
            "MakeSingleSamplesStatic",
            static_cast<void (PrimWriterWrapper<>::*)()>(
                &PrimWriterWrapper<>::MakeSingleSamplesStatic))
        .def(
            "MakeSingleSamplesStatic",
            static_cast<void (PrimWriterWrapper<>::*)(UsdAttribute attr)>(
                &PrimWriterWrapper<>::MakeSingleSamplesStatic))

        .def(
            "_HasAnimCurves",
            &PrimWriterWrapper<>::_HasAnimCurves,
            &PrimWriterWrapper<>::default__HasAnimCurves)
        .def(
            "_GetExportArgs",
            &::unprotect_GetExportArgs,
            boost::python::return_internal_reference<>())
        .def("_GetSparseValueWriter", &::unprotect_GetSparseValueWriter)

        .def(
            "GetDagPath",
            &PrimWriterWrapper<>::GetDagPath,
            boost::python::return_value_policy<boost::python::return_by_value>())
        .def(
            "GetUsdStage",
            &UsdMayaPrimWriter::GetUsdStage,
            boost::python::return_value_policy<boost::python::return_by_value>())
        .def(
            "GetUsdPath",
            &UsdMayaPrimWriter::GetUsdPath,
            boost::python::return_value_policy<boost::python::return_by_value>())

        .def("Register", &PrimWriterWrapper<>::Register)
        .staticmethod("Register")
        .def("Unregister", &PrimWriterWrapper<>::Unregister)
        .staticmethod("Unregister");
}

TF_REGISTRY_FUNCTION(TfEnum)
{
    TF_ADD_ENUM_NAME(UsdMayaShaderWriter::ContextSupport::Supported, "Supported");
    TF_ADD_ENUM_NAME(UsdMayaShaderWriter::ContextSupport::Fallback, "Fallback");
    TF_ADD_ENUM_NAME(UsdMayaShaderWriter::ContextSupport::Unsupported, "Unsupported");
}

//----------------------------------------------------------------------------------------------------------------------
void wrapShaderWriter()
{
    boost::python::
        class_<ShaderWriterWrapper, boost::python::bases<PrimWriterWrapper<>>, boost::noncopyable>
            c("ShaderWriter", boost::python::no_init);

    boost::python::scope s(c);

    TfPyWrapEnum<UsdMayaShaderWriter::ContextSupport>();

    c.def("__init__", make_constructor(&ShaderWriterWrapper::New))
        .def(
            "GetShadingAttributeNameForMayaAttrName",
            &ShaderWriterWrapper::GetShadingAttributeNameForMayaAttrName,
            &ShaderWriterWrapper::default_GetShadingAttributeNameForMayaAttrName)
        .def(
            "GetShadingAttributeForMayaAttrName",
            &ShaderWriterWrapper::GetShadingAttributeForMayaAttrName,
            &ShaderWriterWrapper::default_GetShadingAttributeForMayaAttrName)

        .def("Register", &ShaderWriterWrapper::Register)
        .staticmethod("Register")
        .def("Unregister", &ShaderWriterWrapper::Unregister)
        .staticmethod("Unregister")
        .def("RegisterSymmetric", &ShaderWriterWrapper::RegisterSymmetric)
        .staticmethod("RegisterSymmetric");
}

max_stars_repo_name: sun-frog/maya-usd

max_issues_repo_name: sun-frog/maya-usd

max_forks_repo_name: sun-frog/maya-usd


text:
// Author: Dmitry Kukovinets (d1021976@gmail.com), 24.12.2017, 15:16

#include <boost/asio/io_context.hpp>
#include <boost/asio/system_timer.hpp>

#include <dkuk/coroutine.hpp>

namespace {

int
async_sum_2(int a, int b, dkuk::coroutine_context context)
{
	boost::asio::system_timer timer{context.get_executor().context(), std::chrono::seconds{1}};
	timer.async_wait(context);
	return a + b;
}

int
async_sum_3(int a, int b, int c, dkuk::coroutine_context context)
{
	return async_sum_2(a, b, context) + c;
}

};	// namespace

int
main()
{
	boost::asio::io_context context;

	auto f = dkuk::run_until_complete(context, dkuk::spawn_with_future(context, async_sum_3, 1, 2, 3));
	if (f.get() != 6)
		return 1;

	return 0;
}

ext: cpp


text: #include <boost/range/adaptor/define_adaptor.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// void_cast.cpp: implementation of run-time casting of void pointers

// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// <gennadiy.rozental@tfn.com>

//  See http://www.boost.org for updates, documentation, and revision history.

#if (defined _MSC_VER) && (_MSC_VER == 1200)
# pragma warning (disable : 4786) // too long name, harmless warning
#endif

#include <cassert>

// STL
#include <set>
#include <functional>
#include <algorithm>
#include <cassert>

// BOOST
#include <boost/shared_ptr.hpp>
#define BOOST_SERIALIZATION_SOURCE
#include <boost/serialization/extended_type_info.hpp>
#include <boost/serialization/void_cast.hpp>

namespace boost {
namespace serialization {
namespace void_cast_detail {

struct void_caster_compare
{
    bool
    operator()(
        shared_ptr<const void_caster> lhs,
        shared_ptr<const void_caster> rhs ) const
    {
        if( lhs.get()->m_derived_type < rhs.get()->m_derived_type )
            return true;

        if( rhs.get()->m_derived_type < lhs.get()->m_derived_type)
            return false;

        if( lhs.get()->m_base_type < rhs.get()->m_base_type )
            return true;

        return false;
    }
};

struct null_deleter
{
    void operator()(void const *) const
    {}
};

// it turns out that at least one compiler (msvc 6.0) doesn't guarentee
// to destroy static objects in exactly the reverse sequence that they
// are constructed.  To guarentee this, use a singleton pattern
class void_caster_registry
{
    typedef shared_ptr<const void_caster> value_type;
    typedef std::set<value_type, void_caster_compare> set_type;
    set_type m_set;
    static void_caster_registry * m_self;
    static void_caster_registry *
    self(){
        if(NULL == m_self){
            static void_caster_registry instance;
            m_self = & instance;
        }
        return m_self;
    }
    void_caster_registry(){}
public:
    ~void_caster_registry(){
        m_self = 0;
    }
    typedef set_type::iterator iterator;
    typedef set_type::const_iterator const_iterator;
    static iterator
    begin() {
        return self()->m_set.begin();
    }
    static iterator
    end() {
        return self()->m_set.end();
    }
    static const_iterator
    find(void_caster * vcp){
        return self()->m_set.find(value_type(vcp, null_deleter()));
    }
    static std::pair<iterator, bool>
    insert(const value_type & vcp){
        return self()->m_set.insert(vcp);
    }
    static bool
    empty(){
        if(NULL == m_self)
            return true;
        return m_self->m_set.empty();
    }
    static void
    purge(const extended_type_info * eti);
};

void_caster_registry * void_caster_registry::m_self = NULL;

void
void_caster_registry::purge(const extended_type_info * eti){
    if(NULL == m_self)
        return;
    if(! empty()){
        iterator i = m_self->m_set.begin();
        while(i != m_self->m_set.end()){
            // note that the erase might invalidate i so save it here
            iterator j = i++;
            if((*j)->includes(eti))
                m_self->m_set.erase(j);
        }
    }
}

BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY())
void_caster::void_caster(
    extended_type_info const & derived_type_,
    extended_type_info const & base_type_
) :
    m_derived_type( derived_type_),
    m_base_type(base_type_)
{}

BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY())
void_caster::~void_caster(){}

bool
void_caster::includes(const extended_type_info * eti) const {
    return & m_derived_type == eti || & m_base_type == eti;
}

void BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY())
void_caster::static_register(const void_caster * vcp)
{
    void_caster_registry::insert(shared_ptr<const void_caster>(vcp, null_deleter()));
}

class void_caster_derived : public void_caster
{
    std::ptrdiff_t difference;
    virtual void const*
    upcast( void const* t ) const{
        return static_cast<const char*> ( t ) + difference;
    }
    virtual void const*
    downcast( void const* t ) const{
        return static_cast<const char*> ( t ) - difference;
    }
public:
    void_caster_derived(
        extended_type_info const& derived_type_,
        extended_type_info const& base_type_,
        std::ptrdiff_t difference_
    ) :
        void_caster(derived_type_, base_type_),
        difference( difference_ )
    {}
};

// just used as a search key
class void_caster_argument : public void_caster
{
    virtual void const*
    upcast( void const* t ) const {
        assert(false);
        return NULL;
    }
    virtual void const*
    downcast( void const* t ) const {
        assert(false);
        return NULL;
    }
public:
    void_caster_argument(
        extended_type_info const& derived_type_,
        extended_type_info const& base_type_
    ) :
        void_caster(derived_type_, base_type_)
    {}
};

} // namespace void_cast_detail

void  BOOST_SERIALIZATION_DECL(BOOST_PP_EMPTY())
unregister_void_casts(extended_type_info *eti)
{
    void_cast_detail::void_caster_registry::purge(eti);
}

// Given a void *, assume that it really points to an instance of one type
// and alter it so that it would point to an instance of a related type.
// Return the altered pointer. If there exists no sequence of casts that
// can transform from_type to to_type, return a NULL.

BOOST_SERIALIZATION_DECL(void const *)
void_upcast(
    extended_type_info const & derived_type,
    extended_type_info const & base_type,
    void const * const t,
    bool top
){
    // same types - trivial case
    if (derived_type == base_type)
        return t;

    // check to see if base/derived pair is found in the registry
    void_cast_detail::void_caster_argument ca(derived_type, base_type );
    void_cast_detail::void_caster_registry::const_iterator it;
    it = void_cast_detail::void_caster_registry::find( &ca );

    const void * t_new = NULL;

    // if so
    if (it != void_cast_detail::void_caster_registry::end())
        // we're done
        return (*it)->upcast(t);

    // try to find a chain that gives us what we want
    for(
        it = void_cast_detail::void_caster_registry::begin();
        it != void_cast_detail::void_caster_registry::end();
        ++it
    ){
        // if the current candidate doesn't cast to the desired target type
        if ((*it)->m_base_type == base_type){
            // if the current candidate casts from the desired source type
            if ((*it)->m_derived_type == derived_type){
                // we have a base/derived match - we're done
                // cast to the intermediate type
                t_new = (*it)->upcast(t);
                break;
            }
            t_new = void_upcast(derived_type, (*it)->m_derived_type, t, false);
            if (NULL != t_new){
                t_new = (*it)->upcast(t_new);
                assert(NULL != t_new);
                if(top){
                    // register the this pair so we will have to go through
                    // keep this expensive search process more than once.
                    void_cast_detail::void_caster * vcp =
                        new void_cast_detail::void_caster_derived(
                            derived_type,
                            base_type,
                            static_cast<const char*>(t_new) - static_cast<const char*>(t)
                        );
                    void_cast_detail::void_caster_registry::insert(
                        shared_ptr<const void_cast_detail::void_caster>(vcp)
                    );
                }
                break;
            }
        }
    }
    return t_new;
}

BOOST_SERIALIZATION_DECL(void const *)
void_downcast(
    const extended_type_info & derived_type,
    const extended_type_info & base_type,
    const void * const t,
    bool top
){
    // same types - trivial case
    if (derived_type == base_type)
        return t;

    // check to see if base/derived pair is found in the registry
    void_cast_detail::void_caster_argument ca(derived_type, base_type );
    void_cast_detail::void_caster_registry::const_iterator it;
    it = void_cast_detail::void_caster_registry::find( &ca );

    // if so
    if (it != void_cast_detail::void_caster_registry::end())
        // we're done
        return (*it)->downcast(t);

    const void * t_new = NULL;
    // try to find a chain that gives us what we want
    for(
        it = void_cast_detail::void_caster_registry::begin();
        it != void_cast_detail::void_caster_registry::end();
        ++it
    ){
        // if the current candidate doesn't casts from the desired target type
        if ((*it)->m_derived_type == derived_type){
            // if the current candidate casts to the desired source type
            if ((*it)->m_base_type == base_type){
                // we have a base/derived match - we're done
                // cast to the intermediate type
                t_new = (*it)->downcast(t);
                break;
            }
            t_new = void_downcast((*it)->m_base_type, base_type, t, false);
            if (NULL != t_new){
                t_new = (*it)->downcast(t_new);
                assert(NULL != t_new);
                if(top){
                    // register the this pair so we will have to go through
                    // keep this expensive search process more than once.
                    void_cast_detail::void_caster * vcp =
                        new void_cast_detail::void_caster_derived(
                            derived_type,
                            base_type,
                            static_cast<const char*>(t) - static_cast<const char*>(t_new)
                        );
                    void_cast_detail::void_caster_registry::insert(
                        shared_ptr<const void_cast_detail::void_caster>(vcp)
                    );
                }
                break;
            }
        }
    }
    return t_new;
}

} // namespace serialization
} // namespace boost

// EOF

max_stars_repo_name: spxuw/RFIM

max_issues_repo_name: spxuw/RFIM

max_forks_repo_name: spxuw/RFIM


text:
#include <algorithm>
#include <sstream>
#include <Logging.h>
#include <peptides/Peptide.h>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/categories.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>
#include "immunogenicity/RandomForest.h"

RandomForest::RandomForest(std::istringstream& iss, unsigned int size) {

	boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
	in.push(boost::iostreams::gzip_decompressor());
	in.push(iss);

	std::istream iStream(&in);

	LOG_DEBUG("Loading Random Forest");

	std::string line;
	unsigned level;

	getline(iStream, line); // skip first line

	getline(iStream, line);
	std::istringstream issLine(line);

	while(issLine >> level){
		parameters.emplace_back(level);
	}

	if(size != 0) forest.reserve(size);

	while(getline(iStream, line)){
		forest.emplace_back(parameters, iStream);
	}

	LOG_DEBUG(std::to_string(forest.size()) + " trees loaded");

}

void RandomForest::predictAll(const std::string &pepFile, const Encoder &encoder) const {

	std::ifstream in(pepFile);
	if(in.fail()) throw std::runtime_error("Could not open " + pepFile);

	std::ofstream out(pepFile + ".tmp");
	std::string line;

	getline(in, line); // skip header
	out << "#Peptide\teffectIds\tImmunogenicity" << '\n';

	while(getline(in, line)){

		Peptide peptide = Peptide::parse(line);
		double score = predict(encoder(peptide.getSequence()));
		peptide.setScore(score);
		out << peptide << '\n';
	}

	remove(pepFile.c_str());
	rename((pepFile + ".tmp").c_str(), pepFile.c_str());

}

double RandomForest::predict(const std::vector<Predictor> &predictors) const {

	long posCount = std::count_if(forest.cbegin(), forest.cend(), [&predictors](const auto& tree){
		return tree.predict(predictors);
	});

	return static_cast<double>(posCount) / static_cast<double>(forest.size());
}


text:
//
// Copyright (c) 2011-2012 Krzysztof Jusiak (krzysztof at jusiak dot net)
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef QFSM_FRONT_BASE_FSM_HPP
#define QFSM_FRONT_BASE_FSM_HPP

#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/iteration/local.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/is_sequence.hpp>
#include <boost/mpl/if.hpp>
#include "QFsm/Back/Policy.hpp"
#include "QFsm/Back/Logger.hpp"
#include "QFsm/Back/UnexpectedEvent.hpp"
#include "QFsm/Back/FsmFavor.hpp"
#include "QFsm/Front/Fsm.hpp"
#include "QFsm/Back/Aux/Detail/Pool/Pool.hpp"
#include "QFsm/Back/Aux/Detail/Ctor.hpp"
#include "QFsm/Front/Base/Detail/Keys.hpp"

namespace QFsm
{
namespace Front
{

namespace Detail
{

template
<
    typename TTransitionTable,
    typename TInitialState,
    typename TUnexpectedEvent,
    typename TLogger
>
class Derived
{
public:
    typedef TTransitionTable TransitionTable;
    typedef TInitialState InitialState;
    typedef TUnexpectedEvent UnexpectedEvent;
    typedef TLogger Logger;
};

template<typename TPolicy>
struct BasePolicy : boost::mpl::if_
    <
        boost::is_same<TPolicy, boost::mpl::_1>,
        QFSM_FSM_DEFAULT_POLICY,
        TPolicy
    >
{ };

} // namespace Detail

template
<
    typename T0,
    typename T1 = boost::mpl::_1,
    typename T2 = QFSM_DEFAULT_UNEXPECTED_EVENT,
    typename T3 = QFSM_DEFAULT_LOGGER,
    typename T4 = QFSM_FSM_DEFAULT_POLICY,
    typename Enable = void
>
class Fsm;

template
<
    typename TDerived,
    typename TPolicy
>
class Fsm<TDerived, TPolicy, QFSM_DEFAULT_UNEXPECTED_EVENT/*not used*/, QFSM_DEFAULT_LOGGER/*not used*/, QFSM_FSM_DEFAULT_POLICY/*not used*/, typename boost::disable_if<boost::mpl::is_sequence<TDerived> >::type>
    : public Back::FsmFavor<TDerived, Back::Aux::Detail::Pool::Pool<typename Detail::Keys<typename TDerived::TransitionTable, typename TDerived::UnexpectedEvent, typename TDerived::Logger>::type>, typename Detail::BasePolicy<TPolicy>::type>
{
    typedef Back::FsmFavor<TDerived, Back::Aux::Detail::Pool::Pool<typename Detail::Keys<typename TDerived::TransitionTable, typename TDerived::UnexpectedEvent, typename TDerived::Logger>::type>, typename Detail::BasePolicy<TPolicy>::type> Base;

public:
    CTOR_REF(Fsm, Base, { })
};

template
<
    typename TTransitionTable,
    typename TInitialState,
    typename TUnexpectedEvent,
    typename TLogger,
    typename TPolicy
>
class Fsm<TTransitionTable, TInitialState, TUnexpectedEvent, TLogger, TPolicy, typename boost::enable_if<boost::mpl::is_sequence<TTransitionTable> >::type>
    : public Back::FsmFavor<Detail::Derived<TTransitionTable, TInitialState, TUnexpectedEvent, TLogger>, Back::Aux::Detail::Pool::Pool<typename Detail::Keys<TTransitionTable, TUnexpectedEvent, TLogger>::type>, TPolicy>
{
    typedef Back::FsmFavor<Detail::Derived<TTransitionTable, TInitialState, TUnexpectedEvent, TLogger>, Back::Aux::Detail::Pool::Pool<typename Detail::Keys<TTransitionTable, TUnexpectedEvent, TLogger>::type>, TPolicy> Base;

public:
    CTOR_REF(Fsm, Base, { })
};

} // namespace Front
} // namespace QFsm

#undef QFSM_EXTENSIONS_UML
#undef QFSM_EXTENSIONS_NON_UML

#endif

max_stars_repo_name: krzysztof-jusiak/qfsm

max_issues_repo_name: krzysztof-jusiak/qfsm

max_forks_repo_name: krzysztof-jusiak/qfsm


text:
/*
 * Copyright (c) 2011-2013 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef LIBBITCOIN_VALIDATE_HPP
#define LIBBITCOIN_VALIDATE_HPP

#include <thread>
#include <memory>
#include <boost/optional/optional.hpp>

#include <bitcoin/primitives.hpp>
#include <bitcoin/types.hpp>
#include <bitcoin/threadpool.hpp>
#include <bitcoin/transaction_pool.hpp>

namespace libbitcoin {

/**
 * If you're looking to validate a transaction, then use the simpler
 * transaction_pool::validate() method instead.
 */
class validate_transaction
  : public std::enable_shared_from_this<validate_transaction>
{
public:
    typedef std::function<
        void (const std::error_code&, const index_list&)> validate_handler;

    validate_transaction(
        blockchain& chain, const transaction_type& tx,
        const pool_buffer& pool, async_strand& strand);
    void start(validate_handler handle_validate);

    static std::error_code check_transaction(
        const transaction_type& tx);
    static bool connect_input(
        const transaction_type& tx, size_t current_input,
        const transaction_type& previous_tx, size_t parent_height,
        size_t last_block_height, uint64_t& value_in);
    static bool tally_fees(const transaction_type& tx,
        uint64_t value_in, uint64_t& fees);

private:
    std::error_code basic_checks() const;
    bool is_standard() const;
    const transaction_type* fetch(const hash_digest& tx_hash) const;

    void handle_duplicate_check(const std::error_code& ec);
    bool is_spent(const output_point outpoint) const;

    // Used for checking coinbase maturity
    void set_last_height(const std::error_code& ec, size_t last_height);
    // Begin looping through the inputs, fetching the previous tx
    void next_previous_transaction();
    void previous_tx_index(const std::error_code& ec, size_t parent_height);
    // If previous_tx_index didn't find it then check in pool instead
    void search_pool_previous_tx();
    void handle_previous_tx(const std::error_code& ec,
        const transaction_type& previous_tx, size_t parent_height);
    // After running connect_input, we check whether this
    // validated previous output wasn't already spent by
    // another input in the blockchain.
    // is_spent() earlier already checked in the pool.
    void check_double_spend(const std::error_code& ec);
    // next_previous_transaction();

    void check_fees();

    async_strand& strand_;
    blockchain& chain_;

    const transaction_type tx_;
    const hash_digest tx_hash_;
    const pool_buffer& pool_;
    size_t last_block_height_;
    uint64_t value_in_;
    size_t current_input_;
    index_list unconfirmed_;
    validate_handler handle_validate_;
};

typedef std::shared_ptr<validate_transaction> validate_transaction_ptr;

class validate_block
{
public:
    std::error_code check_block();
    std::error_code accept_block();
    std::error_code connect_block();

protected:
    validate_block(size_t height, const block_type& current_block);

    virtual uint32_t previous_block_bits() = 0;
    virtual uint64_t actual_timespan(const uint64_t interval) = 0;
    virtual uint64_t median_time_past() = 0;
    virtual bool transaction_exists(const hash_digest& tx_hash) = 0;
    virtual bool is_output_spent(const output_point& outpoint) = 0;
    // These have optional implementations that can be overriden
    virtual bool validate_inputs(const transaction_type& tx,
        size_t index_in_parent, uint64_t& value_in, size_t& total_sigops);
    virtual bool connect_input(size_t index_in_parent,
        const transaction_type& current_tx,
        size_t input_index, uint64_t& value_in, size_t& total_sigops);
    virtual bool fetch_transaction(transaction_type& tx,
        size_t& previous_height, const hash_digest& tx_hash) = 0;
    virtual bool is_output_spent(
        const output_point& previous_output,
        size_t index_in_parent, size_t input_index) = 0;
    virtual block_header_type fetch_block(size_t fetch_height) = 0;

private:
    // check_block()
    bool check_proof_of_work(hash_digest hash, uint32_t bits);
    bool check_transaction(const transaction_type& tx);

    size_t legacy_sigops_count();

    // accept_block()
    uint32_t work_required();
    bool passes_checkpoints();
    bool coinbase_height_match();

    // connect_block()
    bool not_duplicate_or_spent(const transaction_type& tx);

    const size_t height_;
    const block_type& current_block_;
};

} // namespace libbitcoin

#endif

max_stars_repo_name: mousewu/bcclient

max_issues_repo_name: mousewu/bcclient

max_forks_repo_name: mousewu/bcclient


text:
#include <iostream>
#include <cmath>
#include <Eigen/Dense>
#include "descentmethods.h"

double F(Eigen::VectorXd x) {
    return pow(x(0), 4.0) + pow(x(0), 2.0) * x(1) + 0.5 * pow(x(0), 2.0) + 3 * x(0) * x(1) + pow(x(1), 2.0);
}

Eigen::VectorXd J(Eigen::VectorXd x) {
    int x_size = x.size();

    Eigen::VectorXd jacobian(x_size);

    jacobian(0) = 4 * pow(x(0), 3.0) + 2 * x(0) * x(1) + x(0) + 3 * x(1);
    jacobian(1) = pow(x(0), 2.0) + 3 * x(0) + 2 * x(1);

    return jacobian;
}

Eigen::MatrixXd H(Eigen::VectorXd x) {
    int x_size = x.size();

    Eigen::MatrixXd hessian(x_size, x_size);

    hessian(0, 0) = 12 * pow(x(0), 2.0) + 2 * x(1) + 1;
    hessian(0, 1) = 2 * x(0) + 3;
    hessian(1, 0) = 2 * x(0) + 3;
    hessian(1, 1) = 2;

    return hessian;
}

int main() {
    Eigen::Vector2d x0;

    x0(0) = -0.5;
    x0(1) = -0.5;

    double epsilon = 0.00001;
    double alpha = 0.3;
    double beta = 0.5;

    Eigen::VectorXd x = DM::Newton(x0, epsilon, alpha, beta, F, J, H);

    std::cout << "The solution is: " << x << std::endl;
    std::cout << "The objective is: " << F(x) << std::endl;
}

max_stars_repo_name: jameshskoh/DescentMethods-CPP

max_issues_repo_name: jameshskoh/DescentMethods-CPP

max_forks_repo_name: jameshskoh/DescentMethods-CPP


text:
#ifndef __LITWINDOW_BOOST_POSIX_TIME_HPP
#define __LITWINDOW_BOOST_POSIX_TIME_HPP

#include <boost/date_time/posix_time/posix_time.hpp>
#include <litwindow/dataadapter.h>

namespace litwindow {
    template <>
    tstring converter<boost::posix_time::ptime>::to_string(const boost::posix_time::ptime &d)
    {
        using namespace boost::posix_time;
        litwindow::tstringstream s;
        boost::date_time::time_facet<ptime, TCHAR> *tfacet(new boost::date_time::time_facet<ptime, TCHAR>(boost::date_time::time_facet<ptime, TCHAR>::iso_time_format_specifier/* _T("%H:%M:%S")*/));
        s.imbue(std::locale(s.getloc(), tfacet));
        s << d;
        return s.str();
    }

    template <>
    size_t converter<boost::posix_time::ptime>::from_string(const tstring &newValue, boost::posix_time::ptime &v)
    {
        using namespace boost::posix_time;
        litwindow::tstringstream s(newValue);
        boost::date_time::time_facet<ptime, TCHAR> *tfacet(new boost::date_time::time_facet<ptime, TCHAR>(boost::date_time::time_facet<ptime, TCHAR>::iso_time_format_specifier/* _T("%H:%M:%S")*/));
        s.imbue(std::locale(s.getloc(), tfacet));
        s >> v;
        return sizeof(v);

    }
}
IMPLEMENT_ADAPTER_TYPE(boost::posix_time::ptime)

#endif

max_stars_repo_name: hajokirchhoff/litwindow

max_issues_repo_name: hajokirchhoff/litwindow

max_forks_repo_name: hajokirchhoff/litwindow


text:
#include "databaseConnectionFactory.h"
#include "databaseManagementOperations.h"
#include "fileSystemOperations.h"
#include "libraryCurrentVersion.h"
#include "sqliteDatabaseOperations.h"
#include "sqliteOperationFactory.h"
#include <boost/date_time/posix_time/ptime.hpp>
#include <fmt/format.h>
#include <stdexcept>

using namespace std;

DatabaseManagementOperations::DatabaseManagementOperations(std::shared_ptr<IFileSystemOperations> fileSystemOperations,
                                                           std::shared_ptr<IDatabaseOperations> databaseOperations,
                                                           std::unique_ptr<IDatabaseConnectionFactory> connectionFactory,
                                                           std::shared_ptr<IStorageOperationFactory> operationFactory)
    : lastError {""},
      fileSystemOperations { fileSystemOperations ?
                             move(fileSystemOperations) :
                             make_shared<FileSystemOperations>() },
      databaseOperations { databaseOperations ?
                           move(databaseOperations) :
                           make_shared<SQLiteDatabaseOperations>() },
      connectionFactory { connectionFactory ?
                          move(connectionFactory) :
                          make_unique<DatabaseConnectionFactory>() },
      operationFactory { operationFactory ?
                         move(operationFactory) :
                         make_shared<SQLiteOperationFactory>() }
{
}

const std::string &DatabaseManagementOperations::getLastError() const
{
    return lastError;
}

bool DatabaseManagementOperations::exist(const std::string &databaseName) const
{
    return fileSystemOperations->fileExists(databaseName);
}

bool DatabaseManagementOperations::create(const string &databaseName)
{
    auto connection { connectionFactory->createNewConnection(databaseName) };
    try {
        connection->openForCreation();
    }
    catch (runtime_error &) {
        lastError = fmt::format("Cannot create database {0}. sqlite3_errmsg(db)", databaseName);
        return false;
    }
    vector<string> tableCreationInstructions {
        "CREATE TABLE city(id INTEGER PRIMARY KEY AUTOINCREMENT, name varchar(50) NOT NULL)",
        "CREATE TABLE school(id INTEGER PRIMARY KEY AUTOINCREMENT, name varchar(50) NOT NULL, city_id INTEGER NOT NULL, FOREIGN KEY(city_id) REFERENCES city(id))",
        "CREATE TABLE class(id INTEGER PRIMARY KEY AUTOINCREMENT, name varchar(50) NOT NULL, school_id INTEGER NOT NULL, UNIQUE(name, school_id), FOREIGN KEY(school_id) REFERENCES school(id))",
        "CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT, firstname varchar(30) NOT NULL, lastname varchar(30) NOT NULL, comments varchar(256))",
        "CREATE TABLE testType(id INTEGER PRIMARY KEY AUTOINCREMENT, name varchar(50) NOT NULL)",
        "CREATE TABLE subject(id INTEGER PRIMARY KEY AUTOINCREMENT, name varchar(50) NOT NULL, isdefault BOOLEAN NOT NULL DEFAULT 0)",
        "CREATE TABLE class_student(class_id INTEGER NOT NULL, student_id INTEGER NOT NULL, PRIMARY KEY(class_id, student_id), FOREIGN KEY(class_id) REFERENCES class(id), FOREIGN KEY(student_id) REFERENCES student(id))",
        "CREATE TABLE assessment(id INTEGER PRIMARY KEY AUTOINCREMENT, name varchar(100) NOT NULL, testType_id INTEGER NOT NULL, subject_id INTEGER NOT NULL, class_id INTEGER NOT NULL, date TEXT NOT NULL, maxScore REAL NOT NULL DEFAULT 100, FOREIGN KEY(testType_id) REFERENCES testType(id), FOREIGN KEY(subject_id) REFERENCES subject(id), FOREIGN KEY(class_id) REFERENCES class(id))",
        "CREATE TABLE assessmentResult(id INTEGER PRIMARY KEY AUTOINCREMENT, assessment_id INTEGER NOT NULL, student_id INTEGER NOT NULL, result REAL NOT NULL, comments varchar(256), FOREIGN KEY(assessment_id) REFERENCES assessment(id), FOREIGN KEY(student_id) REFERENCES student(id))",
        "CREATE TABLE version(name varchar(10) PRIMARY KEY)",
        "INSERT INTO version VALUES ('1.1.0')",
    };
    for(const auto& instruction : tableCreationInstructions) {
        auto operationCreateTableSchool { operationFactory->createDDLOperation(*connection.get(), instruction) };
        if (!operationCreateTableSchool->execute()) {
            lastError = operationCreateTableSchool->getLastError();
            return false;
        }
    }
    return true;
}

bool DatabaseManagementOperations::upgrade(IDatabaseConnection &connection)
{
    //Extract the database folder path
    string originalDBFileName = connection.getDbName();
    string databaseFolderPath = fileSystemOperations->extractFolderPath(originalDBFileName);
    //Generate backup database filename
    string backupDatabaseFileName = generateBackupDatabaseFileName();
    string backupDatabaseFullPath = fmt::format("{0}/{1}", databaseFolderPath, backupDatabaseFileName);
    //Backup the database file
    onUpgradeProgress(100, fmt::format("Backuping the database {0} to {1}...", originalDBFileName, backupDatabaseFullPath));
    if (!fileSystemOperations->fileCopy(originalDBFileName,
                                        backupDatabaseFullPath)) {
        lastError = fileSystemOperations->getLastError();
        return false;
    }
    onUpgradeProgress(0, "Backup succeed");

    DatabaseVersionStorage databaseVersionStorage(connection);
    auto currentDatabaseVersion = databaseVersionStorage.getVersion();
    bool migrationSucceed { false };
    if (currentDatabaseVersion == Version(1, 0, 0)) {
        migrationSucceed = migrateToV1_1_0(connection, databaseVersionStorage);
    }
    //If an error occurred, restore the backup of the database
    if (!migrationSucceed) {
        connection.close();
        onUpgradeProgress(100, fmt::format("Restoring the database backup {0}...", backupDatabaseFullPath));
        if (!fileSystemOperations->fileCopyWithOverwrite(backupDatabaseFullPath,
                                                            originalDBFileName)) {
            lastError = fileSystemOperations->getLastError();
            onUpgradeProgress(100, fmt::format("Unable to restore the database backup {0} to {1}", backupDatabaseFullPath, originalDBFileName));
        }
        else {
            onUpgradeProgress(100, fmt::format("Restoring the database backup completed!", backupDatabaseFullPath));
        }
        onUpgradeProgress(100, "Upgrade failed!");
        return false;
    }
    return true;
}

std::string DatabaseManagementOperations::generateBackupDatabaseFileName() const
{
    boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
    string backupDatabaseFileName = fmt::format("teacherdb_v1.0.0_{0}_{1}_{2}_{3}_{4}_{5}.bak",
                                                now.date().year(),
                                                now.date().month().as_number(),
                                                now.date().day().as_number(),
                                                now.time_of_day().hours(),
                                                now.time_of_day().minutes(),
                                                now.time_of_day().seconds());
    return backupDatabaseFileName;
}

bool DatabaseManagementOperations::migrateToV1_1_0(IDatabaseConnection &connection, DatabaseVersionStorage &databaseVersionStorage)
{
    bool errorOccurred = false;
    onUpgradeProgress(0, "Migration from version 1.0.0 to 1.1.0");
    onUpgradeProgress(0, "Starting the upgrade...");
    //Migrating schema
    vector<string> tableMigrationInstructions {
        "CREATE TABLE version(name varchar(10) PRIMARY KEY)",
        "INSERT INTO version VALUES ('1.1.0')",
        "ALTER TABLE assessment ADD COLUMN maxScore REAL NOT NULL DEFAULT 100"
    };
    int percentCompleted { 0 };
    onUpgradeProgress(percentCompleted, fmt::format("{0}%...", percentCompleted));
    for(const auto& instruction : tableMigrationInstructions) {
        auto operationMigrateTable { operationFactory->createDDLOperation(connection, instruction) };
        if (!operationMigrateTable->execute()) {
            lastError = operationMigrateTable->getLastError();
            errorOccurred = true;
            break;
        }
        else {
            percentCompleted += static_cast<int>((1.0f / static_cast<float>(tableMigrationInstructions.size())) * 80.0f);
            onUpgradeProgress(percentCompleted, fmt::format("{0}%...", percentCompleted));
        }
    }
    //80% completed
    if (!errorOccurred && !databaseVersionStorage.updateVersion(Version(1, 1, 0))) {
        lastError = databaseVersionStorage.getLastError();
        onUpgradeProgress(percentCompleted, lastError);
        errorOccurred = true;
    }
    percentCompleted = 100;
    onUpgradeProgress(percentCompleted, fmt::format("{0}%...", percentCompleted));

    if (!errorOccurred) {
        onUpgradeProgress(percentCompleted, "Upgrade completed!");
    }
    return !errorOccurred;
}

max_stars_repo_name: jeremydumais/TeacherHelper

max_issues_repo_name: jeremydumais/TeacherHelper

max_forks_repo_name: jeremydumais/TeacherHelper