LoginSignup
0
0

More than 3 years have passed since last update.

旧OpenSiv3D(0.4.2)を新バージョンVisualStudio2019(16.6.3)で使うときのエラー対策

Last updated at Posted at 2020-07-07

旧OpenSiv3D(0.4.2)を 新バージョンVisualStudio2019(16.6.3)でビルドするとエラーが出る。

メリット

直せば、他の0.4.2のプロジェクト、すべて直ります。ライブラリ( OpenSiv 0.4.2 )本体のファイルを書き換えますので。

直し方

新規でopenSiv3D(0.4.2)プロジェクトを立ち上げ、ビルドするとエラーが出る。

該当の命令を右クリックして定義先へ飛ぶと InfiniteList.hpp
が表示される。
書き直す前に、バックアップをとっておき、内容を下記のものに書き直す。全部コピーして全部張り付ければOK。
もし何かあったら、バックアップしたInfiniteList.hpp から元通りにすれば大丈夫

InfiniteList.hpp

//-----------------------------------------------
//
//  This file is part of the Siv3D Engine.
//
//  Copyright (c) 2008-2019 Ryo Suzuki
//  Copyright (c) 2016-2019 OpenSiv3D Project
//
//  Licensed under the MIT License.
//
// OpenSiv 0.4.2A version  C++20? C++17? エラー対処対応
//-----------------------------------------------

# pragma once
# include <type_traits>
# include "Fwd.hpp"
# include "Array.hpp"
# include "Step.hpp"


// C++20 check    std::result_of_t(C++17) ==>> std::invoke_result_t(C++20)

#if _MSC_VER >= 1926

#define STD_INVOKE_RESULT_ARG std::invoke_result <Fty(value_type)>
#define STD_INVOKE_RESULT_T_ARG std::invoke_result_t <Fty(value_type)>

#else

#define STD_INVOKE_RESULT_ARG std::result_of <Fty(value_type)>;
#define STD_INVOKE_RESULT_T_ARG std::result_of_t <Fty(value_type)>

#endif


namespace s3d
{
    template <class Type>
    class InfiniteList
    {
    private:

        Type m_startValue;

        Type m_step;

    public:

        class Iterator
        {
        private:

            Type m_currentValue;

            Type m_step;

            template <class IntegerType>
            void checkOverflow() const
            {
                if constexpr (!IsBigInt_v<IntegerType>)
                {
                    bool overflow = false;

                    if (m_step > 0)
                    {
                        if (m_currentValue > std::numeric_limits<Type>::max() - m_step)
                        {
                            overflow = true;
                        }
                    }
                    else if (m_step < 0)
                    {
                        if (m_currentValue < std::numeric_limits<Type>::min() - m_step)
                        {
                            overflow = true;
                        }
                    }

                    if (overflow)
                    {
                        throw std::overflow_error("infinite_iterator: integer overflow");
                    }
                }
            }

        public:

            Iterator()
                : m_currentValue(Type())
                , m_step(Type()) {}

            Iterator(Type startValue, Type step)
                : m_currentValue(startValue)
                , m_step(step) {}

            Iterator& operator ++()
            {
                checkOverflow<Type>();

                m_currentValue += m_step;

                return *this;
            }

            Iterator operator ++(int)
            {
                checkOverflow<Type>();

                Iterator tmp = *this;

                m_currentValue += m_step;

                return tmp;
            }

            const Type& operator *() const { return m_currentValue; }

            const Type* operator ->() const { return &m_currentValue; }

            constexpr bool operator ==(const Iterator&) const { return false; }

            constexpr bool operator !=(const Iterator&) const { return true; }

            Type currentValue() const { return m_currentValue; }

            Type step() const { return m_step; }
        };

        using value_type = Type;
        using iterator = Iterator;

        InfiniteList(Type startValue = 0, Type step = 1)
            : m_startValue(startValue)
            , m_step(step) {}

        iterator begin() const { return iterator(m_startValue, m_step); }

        iterator end() const { return iterator(); }

        value_type startValue() const { return m_startValue; }

        value_type step() const { return m_step; }

        template <class Fty>
        auto filter(Fty f) const;

        template <class Fty>
        auto map(Fty f) const;

        Array<value_type> take(size_t n) const
        {
            Array<value_type> new_array;

            for (auto it = begin(); n--; ++it)
            {
                new_array.push_back(*it);
            }

            return new_array;
        }

        template <class Fty>
        Array<value_type> take_while(Fty f) const
        {
            Array<value_type> new_array;

            for (auto it = begin(); f(*it); ++it)
            {
                new_array.push_back(*it);
            }

            return new_array;
        }
    };

    namespace detail
    {
        template <class StepClass, class ValueType, class Tuple>
        class F_InfStep
        {
        private:

            StepClass m_base;

            Tuple m_functions;

        public:

            using value_type = ValueType;

            F_InfStep(StepClass stepClass, Tuple functions)
                : m_base(stepClass)
                , m_functions(functions) {}

            template <class Fty>
            auto filter(Fty f) const
            {
                const auto functions = std::tuple_cat(m_functions, std::make_tuple(FilterFunction<Fty>{ f }));
                return F_InfStep<StepClass, value_type, decltype(functions)>(m_base, functions);
            }

            template <class Fty>
            auto map(Fty f) const
            {
                using Ret = STD_INVOKE_RESULT_ARG;
                const auto functions = std::tuple_cat(m_functions, std::make_tuple(MapFunction<Fty>{ f }));
                return F_InfStep<StepClass, Ret, decltype(functions)>(m_base, functions);
            }

            Array<value_type> take(size_t n) const
            {
                Array<value_type> new_array;

                if (n == 0)
                {
                    return new_array;
                }

                auto it = m_base.begin();
                const auto pushFunc = [&new_array](const auto& value) { new_array.push_back(value); };
                const auto functions = m_functions;

                for (;;)
                {
                    Apply(pushFunc, *it, functions);

                    if (new_array.size() < n)
                    {
                        ++it;
                    }
                    else
                    {
                        break;
                    }
                }

                return new_array;
            }

            template <class Fty>
            Array<value_type> take_while(Fty f) const
            {
                Array<value_type> new_array;

                bool finished = false;
                auto it = m_base.begin();
                const auto pushFunc = [&new_array, &finished, f = f](const auto& value)
                {
                    if (f(value))
                    {
                        new_array.push_back(value);
                    }
                    else
                    {
                        finished = true;
                    }
                };
                const auto functions = m_functions;

                for (;;)
                {
                    Apply(pushFunc, *it, functions);

                    if (!finished)
                    {
                        ++it;
                    }
                    else
                    {
                        break;
                    }
                }

                return new_array;
            }
        };
    }

    template <class Type>
    template <class Fty>
    inline auto InfiniteList<Type>::filter(Fty f) const
    {
        const auto tuple = std::make_tuple(detail::FilterFunction<Fty>{ f });
        return detail::F_InfStep<InfiniteList, value_type, decltype(tuple)>(*this, tuple);
    }

    template <class Type>
    template <class Fty>
    inline auto InfiniteList<Type>::map(Fty f) const
    {
        using Ret = STD_INVOKE_RESULT_T_ARG; //C++20 std::result_of_t  >>  std::invoke_result_t
        const auto tuple = std::make_tuple(detail::MapFunction<Fty>{ f });
        return detail::F_InfStep<InfiniteList, Ret, decltype(tuple)>(*this, tuple);
    }
}

その他、古い Visual Studio 2019 でも変更支障なし

上記ソースでは古いVisual Studio 2019では、Visual Studio 2019(16.6.3)以上の時だけ変更するように
プリプロセッサ(#if _MSC_VER >= 1926)で分岐させているので、
Visual Studio 2019(16.6.3) を入れていなくても上記を使用しても大丈夫です。

参考サイト

_MSC_VER の参考にしました。ページのずっと下の方に書かれています。
https://docs.microsoft.com/ja-jp/cpp/preprocessor/predefined-macros?view=vs-2019

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0