Модульные тесты для операторов класса шаблона изображения с фреймворком Boost.Test на C ++

Это дополнительный вопрос для тестов для операторов класса шаблонов изображений в C ++. Как упоминалось в ответе Г. Слипена, я пытаюсь использовать Boost.Test и несколько тестовых случаев созданы с BOOST_AUTO_TEST_CASE_TEMPLATE структура.

Экспериментальная реализация

  • Image реализация шаблонного класса (image.h):

    /* Developed by Jimmy Hu */
    
    #ifndef Image_H
    #define Image_H
    
    #include <algorithm>
    #include <array>
    #include <cassert>
    #include <chrono>
    #include <complex>
    #include <concepts>
    #include <fstream>
    #include <functional>
    #include <iostream>
    #include <iterator>
    #include <list>
    #include <numeric>
    #include <string>
    #include <type_traits>
    #include <variant>
    #include <vector>
    
    #include "image_operations.h"
    
    #ifdef USE_BOOST_SERIALIZATION
    #include <boost/archive/binary_oarchive.hpp>
    #include <boost/archive/binary_iarchive.hpp>
    #include <boost/archive/text_iarchive.hpp>
    #include <boost/serialization/array.hpp>
    #include <boost/serialization/base_object.hpp>
    #include <boost/serialization/export.hpp>
    #include <boost/serialization/list.hpp>
    #include <boost/serialization/nvp.hpp>
    #include <boost/serialization/serialization.hpp>
    #include <boost/serialization/split_free.hpp>
    #include <boost/serialization/unique_ptr.hpp>
    #include <boost/serialization/vector.hpp>
    #endif
    
    namespace TinyDIP
    {
        template <typename ElementT>
        class Image
        {
        public:
            Image() = default;
    
            Image(const std::size_t width, const std::size_t height):
                width(width),
                height(height),
                image_data(width * height) { }
    
            Image(const std::size_t width, const std::size_t height, const ElementT initVal):
                width(width),
                height(height),
                image_data(width * height, initVal) {}
    
            Image(const std::vector<ElementT>& input, std::size_t newWidth, std::size_t newHeight):
                width(newWidth),
                height(newHeight)
            {
                assert(input.size() == newWidth * newHeight);
                this->image_data = input;   //  Deep copy
            }
    
            Image(const std::vector<std::vector<ElementT>>& input)
            {
                this->height = input.size();
                this->width = input[0].size();
    
                for (auto& rows : input)
                {
                    this->image_data.insert(this->image_data.end(), std::begin(input), std::end(input));    //  flatten
                }
                return;
            }
    
            constexpr ElementT& at(const unsigned int x, const unsigned int y)
            { 
                checkBoundary(x, y);
                return this->image_data[y * width + x];
            }
    
            constexpr ElementT const& at(const unsigned int x, const unsigned int y) const
            {
                checkBoundary(x, y);
                return this->image_data[y * width + x];
            }
    
            constexpr std::size_t getWidth() const
            {
                return this->width;
            }
    
            constexpr std::size_t getHeight() const
            {
                return this->height;
            }
    
            constexpr auto getSize()
            {
                return std::make_tuple(this->width, this->height);
            }
    
            std::vector<ElementT> const& getImageData() const { return this->image_data; }      //  expose the internal data
    
            void print(std::string separator = "t", std::ostream& os = std::cout)
            {
                for (std::size_t y = 0; y < this->height; ++y)
                {
                    for (std::size_t x = 0; x < this->width; ++x)
                    {
                        //  Ref: https://isocpp.org/wiki/faq/input-output#print-char-or-ptr-as-number
                        os << +this->at(x, y) << separator;
                    }
                    os << "n";
                }
                os << "n";
                return;
            }
    
            //  Enable this function if ElementT = RGB
            void print(std::string separator = "t", std::ostream& os = std::cout) requires(std::same_as<ElementT, RGB>)
            {
                for (std::size_t y = 0; y < this->height; ++y)
                {
                    for (std::size_t x = 0; x < this->width; ++x)
                    {
                        os << "( ";
                        for (std::size_t channel_index = 0; channel_index < 3; ++channel_index)
                        {
                            //  Ref: https://isocpp.org/wiki/faq/input-output#print-char-or-ptr-as-number
                            os << +this->at(x, y).channels[channel_index] << separator;
                        }
                        os << ")" << separator;
                    }
                    os << "n";
                }
                os << "n";
                return;
            }
    
            friend std::ostream& operator<<(std::ostream& os, const Image<ElementT>& rhs)
            {
                const std::string separator = "t";
                for (std::size_t y = 0; y < rhs.height; ++y)
                {
                    for (std::size_t x = 0; x < rhs.width; ++x)
                    {
                        //  Ref: https://isocpp.org/wiki/faq/input-output#print-char-or-ptr-as-number
                        os << +rhs.at(x, y) << separator;
                    }
                    os << "n";
                }
                os << "n";
                return os;
            }
    
            Image<ElementT>& operator+=(const Image<ElementT>& rhs)
            {
                assert(rhs.width == this->width);
                assert(rhs.height == this->height);
                std::transform(image_data.cbegin(), image_data.cend(), rhs.image_data.cbegin(),
                       image_data.begin(), std::plus<>{});
                return *this;
            }
    
            Image<ElementT>& operator-=(const Image<ElementT>& rhs)
            {
                assert(rhs.width == this->width);
                assert(rhs.height == this->height);
                std::transform(image_data.cbegin(), image_data.cend(), rhs.image_data.cbegin(),
                       image_data.begin(), std::minus<>{});
                return *this;
            }
    
            Image<ElementT>& operator*=(const Image<ElementT>& rhs)
            {
                assert(rhs.width == this->width);
                assert(rhs.height == this->height);
                std::transform(image_data.cbegin(), image_data.cend(), rhs.image_data.cbegin(),
                       image_data.begin(), std::multiplies<>{});
                return *this;
            }
    
            Image<ElementT>& operator/=(const Image<ElementT>& rhs)
            {
                assert(rhs.width == this->width);
                assert(rhs.height == this->height);
                std::transform(image_data.cbegin(), image_data.cend(), rhs.image_data.cbegin(),
                       image_data.begin(), std::divides<>{});
                return *this;
            }
    
            bool operator==(const Image<ElementT>& rhs) const
            {
                /* do actual comparison */
                if (rhs.width != this->width ||
                    rhs.height != this->height)
                {
                    return false;
                }
                return rhs.image_data == this->image_data;
            }
    
            bool operator!=(const Image<ElementT>& rhs) const
            {
                return !(this == rhs);
            }
    
            Image<ElementT>& operator=(Image<ElementT> const& input) = default;  //  Copy Assign
    
            Image<ElementT>& operator=(Image<ElementT>&& other) = default;       //  Move Assign
    
            Image(const Image<ElementT> &input) = default;                       //  Copy Constructor
    
            Image(Image<ElementT> &&input) = default;                            //  Move Constructor
    
    #ifdef USE_BOOST_SERIALIZATION
    
            void Save(std::string filename)
            {
                const std::string filename_with_extension = filename + ".dat";
                //    Reference: https://stackoverflow.com/questions/523872/how-do-you-serialize-an-object-in-c
                std::ofstream ofs(filename_with_extension, std::ios::binary);
                boost::archive::binary_oarchive ArchiveOut(ofs);
                //    write class instance to archive
                ArchiveOut << *this;
                //    archive and stream closed when destructors are called
                ofs.close();
            }
    #endif
        private:
            std::size_t width;
            std::size_t height;
            std::vector<ElementT> image_data;
    
            void checkBoundary(const size_t x, const size_t y) const
            {
                assert(x < width);
                assert(y < height);
            }
    
    #ifdef USE_BOOST_SERIALIZATION
            friend class boost::serialization::access;
            template<class Archive>
            void serialize(Archive& ar, const unsigned int version)
            {
                ar& width;
                ar& height;
                ar& image_data;
            }
    #endif
    
        };
    }
    
    #endif
    
  • image_operations.h:

    /* Developed by Jimmy Hu */
    
    #ifndef ImageOperations_H
    #define ImageOperations_H
    
    #include <numbers>
    #include <string>
    #include "base_types.h"
    #include "image.h"
    
    #define is_size_same(x, y) {assert(x.getWidth() == y.getWidth()); assert(x.getHeight() == y.getHeight());}
    
    namespace TinyDIP
    {
        // Forward Declaration class Image
        template <typename ElementT>
        class Image;
    
        template<class T = GrayScale>
        requires (std::same_as<T, GrayScale>)
        constexpr static auto constructRGB(Image<T> r, Image<T> g, Image<T> b)
        {
            is_size_same(r, g);
            is_size_same(g, b);
            is_size_same(r, b);
            return;
        }
    
        template<typename T>
        T normalDistribution1D(const T x, const T standard_deviation)
        {
            return std::exp(-x * x / (2 * standard_deviation * standard_deviation));
        }
    
        template<typename T>
        T normalDistribution2D(const T xlocation, const T ylocation, const T standard_deviation)
        {
            return std::exp(-(xlocation * xlocation + ylocation * ylocation) / (2 * standard_deviation * standard_deviation)) / (2 * std::numbers::pi * standard_deviation * standard_deviation);
        }
    
        template<class InputT1, class InputT2>
        constexpr static auto cubicPolate(const InputT1 v0, const InputT1 v1, const InputT1 v2, const InputT1 v3, const InputT2 frac)
        {
            auto A = (v3-v2)-(v0-v1);
            auto B = (v0-v1)-A;
            auto C = v2-v0;
            auto D = v1;
            return D + frac * (C + frac * (B + frac * A));
        }
    
        template<class InputT = float, class ElementT>
        constexpr static auto bicubicPolate(const ElementT* const ndata, const InputT fracx, const InputT fracy)
        {
            auto x1 = cubicPolate( ndata[0], ndata[1], ndata[2], ndata[3], fracx );
            auto x2 = cubicPolate( ndata[4], ndata[5], ndata[6], ndata[7], fracx );
            auto x3 = cubicPolate( ndata[8], ndata[9], ndata[10], ndata[11], fracx );
            auto x4 = cubicPolate( ndata[12], ndata[13], ndata[14], ndata[15], fracx );
    
            return std::clamp(
                        cubicPolate( x1, x2, x3, x4, fracy ), 
                        static_cast<InputT>(std::numeric_limits<ElementT>::min()),
                        static_cast<InputT>(std::numeric_limits<ElementT>::max()));
        }
    
        template<class FloatingType = float, class ElementT>
        Image<ElementT> copyResizeBicubic(Image<ElementT>& image, size_t width, size_t height)
        {
            auto output = Image<ElementT>(width, height);
            //  get used to the C++ way of casting
            auto ratiox = static_cast<FloatingType>(image.getWidth()) / static_cast<FloatingType>(width);
            auto ratioy = static_cast<FloatingType>(image.getHeight()) / static_cast<FloatingType>(height);
    
            for (size_t y = 0; y < height; ++y)
            {
                for (size_t x = 0; x < width; ++x)
                {
                    FloatingType xMappingToOrigin = static_cast<FloatingType>(x) * ratiox;
                    FloatingType yMappingToOrigin = static_cast<FloatingType>(y) * ratioy;
                    FloatingType xMappingToOriginFloor = std::floor(xMappingToOrigin);
                    FloatingType yMappingToOriginFloor = std::floor(yMappingToOrigin);
                    FloatingType xMappingToOriginFrac = xMappingToOrigin - xMappingToOriginFloor;
                    FloatingType yMappingToOriginFrac = yMappingToOrigin - yMappingToOriginFloor;
    
                    ElementT ndata[4 * 4];
                    for (int ndatay = -1; ndatay <= 2; ++ndatay)
                    {
                        for (int ndatax = -1; ndatax <= 2; ++ndatax)
                        {
                            ndata[(ndatay + 1) * 4 + (ndatax + 1)] = image.at(
                                std::clamp(xMappingToOriginFloor + ndatax, static_cast<FloatingType>(0), image.getWidth() - static_cast<FloatingType>(1)), 
                                std::clamp(yMappingToOriginFloor + ndatay, static_cast<FloatingType>(0), image.getHeight() - static_cast<FloatingType>(1)));
                        }
    
                    }
                    output.at(x, y) = bicubicPolate(ndata, xMappingToOriginFrac, yMappingToOriginFrac);
                }
            }
            return output;
        }
    
        //  multiple standard deviations
        template<class InputT>
        constexpr static Image<InputT> gaussianFigure2D(
            const size_t xsize, const size_t ysize, 
            const size_t centerx, const size_t centery,
            const InputT standard_deviation_x, const InputT standard_deviation_y)
        {
            auto output = TinyDIP::Image<InputT>(xsize, ysize);
            auto row_vector_x = TinyDIP::Image<InputT>(xsize, 1);
            for (size_t x = 0; x < xsize; ++x)
            {
                row_vector_x.at(x, 0) = normalDistribution1D(static_cast<InputT>(x) - static_cast<InputT>(centerx), standard_deviation_x);
            }
    
            auto row_vector_y = TinyDIP::Image<InputT>(ysize, 1);
            for (size_t y = 0; y < ysize; ++y)
            {
                row_vector_y.at(y, 0) = normalDistribution1D(static_cast<InputT>(y) - static_cast<InputT>(centery), standard_deviation_y);
            }
    
            for (size_t y = 0; y < ysize; ++y)
            {
                for (size_t x = 0; x < xsize; ++x)
                {
                    output.at(x, y) = row_vector_x.at(x, 0) * row_vector_y.at(y, 0);
                }
            }
            return output;
        }
    
        //  single standard deviation
        template<class InputT>
        constexpr static Image<InputT> gaussianFigure2D(
            const size_t xsize, const size_t ysize,
            const size_t centerx, const size_t centery,
            const InputT standard_deviation)
        {
            return gaussianFigure2D(xsize, ysize, centerx, centery, standard_deviation, standard_deviation);
        }
    
        template<typename Op, class InputT, class... Args>
        constexpr static Image<InputT> pixelwiseOperation(Op op, const Image<InputT>& input1, const Args&... inputs)
        {
            Image<InputT> output(
                recursive_transform<1>(
                    [&](auto&& element1, auto&&... elements) 
                        {
                            auto result = op(element1, elements...);
                            return static_cast<InputT>(std::clamp(
                                result,
                                static_cast<decltype(result)>(std::numeric_limits<InputT>::min()),
                                static_cast<decltype(result)>(std::numeric_limits<InputT>::max())));
                        },
                    (input1.getImageData()),
                    (inputs.getImageData())...),
                input1.getWidth(),
                input1.getHeight());
            return output;
        }
    
        template<class InputT>
        constexpr static Image<InputT> plus(const Image<InputT>& input1)
        {
            return input1;
        }
    
        template<class InputT, class... Args>
        constexpr static Image<InputT> plus(const Image<InputT>& input1, const Args&... inputs)
        {
            return TinyDIP::pixelwiseOperation(std::plus<>{}, input1, plus(inputs...));
        }
    
        template<class InputT>
        constexpr static Image<InputT> subtract(const Image<InputT>& input1, const Image<InputT>& input2)
        {
            is_size_same(input1, input2);
            return TinyDIP::pixelwiseOperation(std::minus<>{}, input1, input2);
        }
    
        template<class InputT = RGB>
        requires (std::same_as<InputT, RGB>)
        constexpr static Image<InputT> subtract(Image<InputT>& input1, Image<InputT>& input2)
        {
            is_size_same(input1, input2);
            Image<InputT> output(input1.getWidth(), input1.getHeight());
            for (std::size_t y = 0; y < input1.getHeight(); ++y)
            {
                for (std::size_t x = 0; x < input1.getWidth(); ++x)
                {
                    for(std::size_t channel_index = 0; channel_index < 3; ++channel_index)
                    {
                        output.at(x, y).channels[channel_index] = 
                        std::clamp(
                            input1.at(x, y).channels[channel_index] - 
                            input2.at(x, y).channels[channel_index],
                            0,
                            255);
                    }
                }
            }
            return output;
        }
    
        template<class InputT>
        constexpr static Image<InputT> multiplies(const Image<InputT>& input1, const Image<InputT>& input2)
        {
            return TinyDIP::pixelwiseOperation(std::multiplies<>{}, input1, input2);
        }
    
        template<class InputT, class... Args>
        constexpr static Image<InputT> multiplies(const Image<InputT>& input1, const Args&... inputs)
        {
            return TinyDIP::pixelwiseOperation(std::multiplies<>{}, input1, multiplies(inputs...));
        }
    
        template<class InputT>
        constexpr static Image<InputT> divides(const Image<InputT>& input1, const Image<InputT>& input2)
        {
            return TinyDIP::pixelwiseOperation(std::divides<>{}, input1, input2);
        }
    
        template<class InputT>
        constexpr static Image<InputT> modulus(const Image<InputT>& input1, const Image<InputT>& input2)
        {
            return TinyDIP::pixelwiseOperation(std::modulus<>{}, input1, input2);
        }
    
        template<class InputT>
        constexpr static Image<InputT> negate(const Image<InputT>& input1, const Image<InputT>& input2)
        {
            return TinyDIP::pixelwiseOperation(std::negate<>{}, input1);
        }
    }
    
    #endif
    
  • base_types.h: Базовые типы

    /* Developed by Jimmy Hu */
    
    #ifndef BASE_H
    #define BASE_H
    
    #include <filesystem>
    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string>
    #include <utility>
    
    using BYTE = unsigned char;
    
    struct RGB
    {
        BYTE channels[3];
    };
    
    using GrayScale = BYTE;
    
    struct HSV
    {
        double channels[3];    //  Range: 0 <= H < 360, 0 <= S <= 1, 0 <= V <= 255
    };
    
    struct BMPIMAGE
    {
        std::filesystem::path FILENAME;
    
        unsigned int XSIZE;
        unsigned int YSIZE;
        BYTE FILLINGBYTE;
        BYTE *IMAGE_DATA;
    };
    #endif
    

Модульные тесты с Boost.Test

#define BOOST_TEST_DYN_LINK

#define BOOST_TEST_MODULE image_elementwise_tests

#ifdef BOOST_TEST_MODULE
#include <boost/test/included/unit_test.hpp>


#ifdef BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
#else
#include <boost/test/included/unit_test.hpp>
#endif // BOOST_TEST_DYN_LINK

#include <boost/mpl/list.hpp>
#include <boost/mpl/vector.hpp>
#include <tao/tuple/tuple.hpp>

typedef boost::mpl::list<
    byte, char, int, short, long, long long int,
    unsigned int, unsigned short int, unsigned long int, unsigned long long int,
    float, double, long double> test_types;

BOOST_AUTO_TEST_CASE_TEMPLATE(image_elementwise_add_test, T, test_types)
{
    std::size_t size_x = 10;
    std::size_t size_y = 10;
    T initVal = 10;
    T increment = 1;
    auto test = TinyDIP::Image<T>(size_x, size_y, initVal);
    test += TinyDIP::Image<T>(size_x, size_y, increment);
    BOOST_TEST(test == TinyDIP::Image<T>(size_x, size_y, initVal + increment));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(image_elementwise_add_test_zero_dimensions, T, test_types)
{
    std::size_t size_x = 0;                         //  Test images with both of the dimensions having size zero.
    std::size_t size_y = 0;                         //  Test images with both of the dimensions having size zero.
    T initVal = 10;
    T increment = 1;
    auto test = TinyDIP::Image<T>(size_x, size_y, initVal);
    test += TinyDIP::Image<T>(size_x, size_y, increment);
    BOOST_TEST(test == TinyDIP::Image<T>(size_x, size_y, initVal + increment));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(image_elementwise_add_test_large_dimensions, T, test_types)
{
    std::size_t size_x = 18446744073709551615;       //  Test images with very large dimensions (std::numeric_limits<std::size_t>::max()).
    std::size_t size_y = 18446744073709551615;       //  Test images with very large dimensions (std::numeric_limits<std::size_t>::max()).
    T initVal = 10;
    T increment = 1;
    auto test = TinyDIP::Image<T>(size_x, size_y, initVal);
    test += TinyDIP::Image<T>(size_x, size_y, increment);
    BOOST_TEST(test == TinyDIP::Image<T>(size_x, size_y, initVal + increment));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(image_elementwise_minus_test, T, test_types)
{
    std::size_t size_x = 10;
    std::size_t size_y = 10;
    T initVal = 10;
    T difference = 1;
    auto test = TinyDIP::Image<T>(size_x, size_y, initVal);
    test -= TinyDIP::Image<T>(size_x, size_y, difference);
    BOOST_TEST(test == TinyDIP::Image<T>(size_x, size_y, initVal - difference));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(image_elementwise_minus_test_zero_dimensions, T, test_types)
{
    std::size_t size_x = 0;                         //  Test images with both of the dimensions having size zero.
    std::size_t size_y = 0;                         //  Test images with both of the dimensions having size zero.
    T initVal = 10;
    T difference = 1;
    auto test = TinyDIP::Image<T>(size_x, size_y, initVal);
    test -= TinyDIP::Image<T>(size_x, size_y, difference);
    BOOST_TEST(test == TinyDIP::Image<T>(size_x, size_y, initVal - difference));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(image_elementwise_minus_test_large_dimensions, T, test_types)
{
    std::size_t size_x = 18446744073709551615;       //  Test images with very large dimensions (std::numeric_limits<std::size_t>::max()).
    std::size_t size_y = 18446744073709551615;       //  Test images with very large dimensions (std::numeric_limits<std::size_t>::max()).
    T initVal = 10;
    T difference = 1;
    auto test = TinyDIP::Image<T>(size_x, size_y, initVal);
    test -= TinyDIP::Image<T>(size_x, size_y, difference);
    BOOST_TEST(test == TinyDIP::Image<T>(size_x, size_y, initVal - difference));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(image_elementwise_multiplies_test, T, test_types)
{
    std::size_t size_x = 10;
    std::size_t size_y = 10;
    T initVal = 10;
    T multiplier = 2;
    auto test = TinyDIP::Image<T>(size_x, size_y, initVal);
    test *= TinyDIP::Image<T>(size_x, size_y, multiplier);
    BOOST_TEST(test == TinyDIP::Image<T>(size_x, size_y, initVal * multiplier));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(image_elementwise_multiplies_test_zero_dimensions, T, test_types)
{
    std::size_t size_x = 0;                         //  Test images with both of the dimensions having size zero.
    std::size_t size_y = 0;                         //  Test images with both of the dimensions having size zero.
    T initVal = 10;
    T multiplier = 2;
    auto test = TinyDIP::Image<T>(size_x, size_y, initVal);
    test *= TinyDIP::Image<T>(size_x, size_y, multiplier);
    BOOST_TEST(test == TinyDIP::Image<T>(size_x, size_y, initVal * multiplier));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(image_elementwise_multiplies_test_large_dimensions, T, test_types)
{
    std::size_t size_x = 18446744073709551615;       //  Test images with very large dimensions (std::numeric_limits<std::size_t>::max()).
    std::size_t size_y = 18446744073709551615;       //  Test images with very large dimensions (std::numeric_limits<std::size_t>::max()).
    T initVal = 10;
    T multiplier = 2;
    auto test = TinyDIP::Image<T>(size_x, size_y, initVal);
    test *= TinyDIP::Image<T>(size_x, size_y, multiplier);
    BOOST_TEST(test == TinyDIP::Image<T>(size_x, size_y, initVal * multiplier));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(image_elementwise_divides_test, T, test_types)
{
    std::size_t size_x = 10;
    std::size_t size_y = 10;
    T initVal = 10;
    T divider = 2;
    auto test = TinyDIP::Image<T>(size_x, size_y, initVal);
    test /= TinyDIP::Image<T>(size_x, size_y, divider);
    BOOST_TEST(test == TinyDIP::Image<T>(size_x, size_y, initVal / divider));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(image_elementwise_divides_test_zero_dimensions, T, test_types)
{
    std::size_t size_x = 0;                         //  Test images with both of the dimensions having size zero.
    std::size_t size_y = 0;                         //  Test images with both of the dimensions having size zero.
    T initVal = 10;
    T divider = 2;
    auto test = TinyDIP::Image<T>(size_x, size_y, initVal);
    test /= TinyDIP::Image<T>(size_x, size_y, divider);
    BOOST_TEST(test == TinyDIP::Image<T>(size_x, size_y, initVal / divider));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(image_elementwise_divides_test_large_dimensions, T, test_types)
{
    std::size_t size_x = 18446744073709551615;       //  Test images with very large dimensions (std::numeric_limits<std::size_t>::max()).
    std::size_t size_y = 18446744073709551615;       //  Test images with very large dimensions (std::numeric_limits<std::size_t>::max()).
    T initVal = 10;
    T divider = 2;
    auto test = TinyDIP::Image<T>(size_x, size_y, initVal);
    test /= TinyDIP::Image<T>(size_x, size_y, divider);
    BOOST_TEST(test == TinyDIP::Image<T>(size_x, size_y, initVal / divider));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(image_elementwise_divides_zero_test, T, test_types)
{
    std::size_t size_x = 10;
    std::size_t size_y = 10;
    T initVal = 10;
    T divider = 0;
    auto test = TinyDIP::Image<T>(size_x, size_y, initVal);
    test /= TinyDIP::Image<T>(size_x, size_y, divider);
    BOOST_TEST(test == TinyDIP::Image<T>(size_x, size_y, initVal / divider));       //  dividing by zero test
}

#endif

Все предложения приветствуются.

Сводная информация:

  • На какой вопрос это продолжение?

    Тесты для операторов класса шаблона изображения в C ++

  • Какие изменения были внесены в код с момента последнего вопроса?

    В этом посте я пытаюсь создать несколько тестовых примеров с помощью фреймворка Boost.Test.

  • Почему запрашивается новый обзор?

    Если есть какие-то улучшения, пожалуйста, дайте мне знать.

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *