Skip to content

Commit

Permalink
Add support for <filesystem> to IO (#636)
Browse files Browse the repository at this point in the history
If neither <filesystem> nor <experimental/filesystem> is detected,
then require <boost/filesystem.hpp>.

If user defines BOOST_GIL_IO_USE_BOOST_FILESYSTEM macro,
then <boost/filesystem.hpp> is pre-selected and required,
and search for any of the C++ standard implementation is skipped.

Remove end-user macro BOOST_GIL_IO_ADD_FS_PATH_SUPPORT
Require tests to always build with support of either
detected C++ filesystem or pre-selected Boost.Filesystem.

Closes ##222
  • Loading branch information
mloskot committed Feb 22, 2022
1 parent 9bd8642 commit f4c70a8
Show file tree
Hide file tree
Showing 20 changed files with 100 additions and 124 deletions.
15 changes: 8 additions & 7 deletions doc/io.rst
Expand Up @@ -205,9 +205,10 @@ If that's the case the user has to use the xxx_and_convert_xxx variants.

All functions take the filename or a device as the first parameter.
The filename can be anything from a C-string, ``std::string``,
``std::wstring`` and ``boost::filesystem`` path. When using the path
object the user needs to define the ADD_FS_PATH_SUPPORT compiler symbol to
include the boost::filesystem dependency.
``std::wstring`` to ``std::filesystem`` and ``boost::filesystem`` path.
The availability of the ``std::filesystem`` is detected automatically,
unless ``BOOST_GIL_IO_USE_BOOST_FILESYSTEM`` macro is defined that forces
preference of the Boost.Filesystem.
Devices could be a ``FILE*``, ``std::ifstream``, and ``TIFF*`` for TIFF images.

The second parameter is either an image or view type depending on the
Expand Down Expand Up @@ -303,9 +304,10 @@ Write Interface
There is only one function for writing out images, write_view.
Similar to reading the first parameter is either a filename or a device.
The filename can be anything from a C-string, ``std::string``,
``std::wstring``, and ``boost::filesystem`` path. When using the path object
the user needs to define the ``ADD_FS_PATH_SUPPORT`` compiler symbol to
include the ``boost::filesystem`` dependency.
``std::wstring`` to ``std::filesystem`` and ``boost::filesystem`` path.
The availability of the ``std::filesystem`` is detected automatically,
unless ``BOOST_GIL_IO_USE_BOOST_FILESYSTEM`` macro is defined that forces
preference of the Boost.Filesystem.
Devices could be ``FILE*``, ``std::ifstream``, and ``TIFF*`` for TIFF images.

The second parameter is an view object to image being written.
Expand Down Expand Up @@ -342,7 +344,6 @@ that can be set by the user:
Symbol Description
======================================================== ========================================================
BOOST_GIL_IO_ENABLE_GRAY_ALPHA Enable the color space "gray_alpha".
BOOST_GIL_IO_ADD_FS_PATH_SUPPORT Enable boost::filesystem 3.0 library.
BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED Use libpng in floating point mode. This symbol is incompatible with BOOST_GIL_IO_PNG_FIXED_POINT_SUPPORTED.
BOOST_GIL_IO_PNG_FIXED_POINT_SUPPORTED Use libpng in integer mode. This symbol is incompatible with BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED.
BOOST_GIL_IO_PNG_DITHERING_SUPPORTED Look up "dithering" in libpng manual for explanation.
Expand Down
65 changes: 65 additions & 0 deletions include/boost/gil/io/detail/filesystem.hpp
@@ -0,0 +1,65 @@
//
// Copyright 2022 Mateusz Loskot <mateusz at loskot 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 BOOST_GIL_IO_DETAIL_FILESYSTEM_HPP
#define BOOST_GIL_IO_DETAIL_FILESYSTEM_HPP

#include <boost/config.hpp>

#if !defined(BOOST_GIL_IO_USE_BOOST_FILESYSTEM)
#if !defined(BOOST_NO_CXX17_HDR_FILESYSTEM) || defined(__cpp_lib_filesystem)
#include <filesystem>
#define BOOST_GIL_IO_USE_STD_FILESYSTEM
#elif defined(__cpp_lib_experimental_filesystem)
#include <experimental/filesystem>
#define BOOST_GIL_IO_USE_STD_FILESYSTEM
#define BOOST_GIL_IO_USE_STD_EXPERIMENTAL_FILESYSTEM
#endif
#endif // !BOOST_GIL_IO_USE_BOOST_FILESYSTEM

#if !defined(BOOST_GIL_IO_USE_STD_FILESYSTEM)
// Disable warning: conversion to 'std::atomic<int>::__integral_type {aka int}' from 'long int' may alter its value
#if defined(BOOST_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
#endif

#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
#endif

#define BOOST_FILESYSTEM_VERSION 3
#include <boost/filesystem.hpp>
#define BOOST_GIL_IO_USE_BOOST_FILESYSTEM

#if defined(BOOST_CLANG)
#pragma clang diagnostic pop
#endif

#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic pop
#endif

#endif

namespace boost { namespace gil { namespace detail {

#if defined(BOOST_GIL_IO_USE_STD_EXPERIMENTAL_FILESYSTEM)
namespace filesystem = std::experimental::filesystem;
#elif defined(BOOST_GIL_IO_USE_STD_FILESYSTEM)
namespace filesystem = std::filesystem;
#else
#if !defined(BOOST_GIL_IO_USE_BOOST_FILESYSTEM)
#error "Boost.Filesystem is required if C++17 <filesystem> is not available"
#endif
namespace filesystem = boost::filesystem;
#endif

}}} // namespace boost::gil::detail

#endif
4 changes: 1 addition & 3 deletions include/boost/gil/io/make_backend.hpp
Expand Up @@ -55,17 +55,15 @@ auto make_reader_backend(
return reader_backend<device_t, FormatTag>(device, settings);
}

#ifdef BOOST_GIL_IO_ADD_FS_PATH_SUPPORT
template <typename FormatTag>
inline
auto make_reader_backend(
filesystem::path const& path,
detail::filesystem::path const& path,
image_read_settings<FormatTag> const& settings)
-> typename get_reader_backend<std::wstring, FormatTag>::type
{
return make_reader_backend(path.wstring(), settings);
}
#endif // BOOST_GIL_IO_ADD_FS_PATH_SUPPORT

template <typename Device, typename FormatTag>
inline
Expand Down
8 changes: 2 additions & 6 deletions include/boost/gil/io/make_dynamic_image_reader.hpp
Expand Up @@ -54,16 +54,14 @@ auto make_dynamic_image_reader(
typename get_dynamic_image_reader<std::wstring, FormatTag>::type(device, settings);
}

#ifdef BOOST_GIL_IO_ADD_FS_PATH_SUPPORT
template <typename FormatTag>
inline
auto make_dynamic_image_reader(
filesystem::path const& path, image_read_settings<FormatTag> const& settings)
detail::filesystem::path const& path, image_read_settings<FormatTag> const& settings)
-> typename get_dynamic_image_reader<std::wstring, FormatTag>::type
{
return make_dynamic_image_reader(path.wstring(), settings);
}
#endif // BOOST_GIL_IO_ADD_FS_PATH_SUPPORT

template <typename Device, typename FormatTag>
inline
Expand Down Expand Up @@ -109,15 +107,13 @@ auto make_dynamic_image_reader(std::wstring const& file_name, FormatTag const&)
return make_dynamic_image_reader(file_name, image_read_settings<FormatTag>());
}

#ifdef BOOST_GIL_IO_ADD_FS_PATH_SUPPORT
template <typename FormatTag>
inline
auto make_dynamic_image_reader(filesystem::path const& path, FormatTag const&)
auto make_dynamic_image_reader(detail::filesystem::path const& path, FormatTag const&)
-> typename get_dynamic_image_reader<std::wstring, FormatTag>::type
{
return make_dynamic_image_reader(path.wstring(), image_read_settings<FormatTag>());
}
#endif // BOOST_GIL_IO_ADD_FS_PATH_SUPPORT

template <typename Device, typename FormatTag>
inline
Expand Down
4 changes: 2 additions & 2 deletions include/boost/gil/io/make_dynamic_image_writer.hpp
Expand Up @@ -69,8 +69,8 @@ inline
typename get_dynamic_image_writer< std::wstring
, FormatTag
>::type
make_dynamic_image_writer( const filesystem::path& path
, const image_write_info< FormatTag >& info
make_dynamic_image_writer( detail::filesystem::path const& path
, image_write_info<FormatTag> const& info
)
{
return make_dynamic_image_writer( path.wstring()
Expand Down
8 changes: 2 additions & 6 deletions include/boost/gil/io/make_reader.hpp
Expand Up @@ -70,7 +70,6 @@ make_reader( const std::wstring& file_name
);
}

#ifdef BOOST_GIL_IO_ADD_FS_PATH_SUPPORT
template< typename FormatTag
, typename ConversionPolicy
>
Expand All @@ -79,7 +78,7 @@ typename get_reader< std::wstring
, FormatTag
, ConversionPolicy
>::type
make_reader( const filesystem::path& path
make_reader( detail::filesystem::path const& path
, const image_read_settings< FormatTag >& settings
, const ConversionPolicy& cc
)
Expand All @@ -89,7 +88,6 @@ make_reader( const filesystem::path& path
, cc
);
}
#endif // BOOST_GIL_IO_ADD_FS_PATH_SUPPORT

template <typename Device, typename FormatTag, typename ConversionPolicy>
inline
Expand Down Expand Up @@ -153,7 +151,6 @@ make_reader( const std::wstring& file_name
);
}

#ifdef BOOST_GIL_IO_ADD_FS_PATH_SUPPORT
template< typename FormatTag
, typename ConversionPolicy
>
Expand All @@ -162,7 +159,7 @@ typename get_reader< std::wstring
, FormatTag
, ConversionPolicy
>::type
make_reader( const filesystem::path& path
make_reader( detail::filesystem::path const& path
, const FormatTag&
, const ConversionPolicy& cc
)
Expand All @@ -172,7 +169,6 @@ make_reader( const filesystem::path& path
, cc
);
}
#endif // BOOST_GIL_IO_ADD_FS_PATH_SUPPORT

template <typename Device, typename FormatTag, typename ConversionPolicy>
inline
Expand Down
4 changes: 1 addition & 3 deletions include/boost/gil/io/make_scanline_reader.hpp
Expand Up @@ -63,21 +63,19 @@ make_scanline_reader( const std::wstring& file_name
);
}

#ifdef BOOST_GIL_IO_ADD_FS_PATH_SUPPORT
template< typename FormatTag >
inline
typename get_scanline_reader< std::wstring
, FormatTag
>::type
make_scanline_reader( const filesystem::path& path
make_scanline_reader( detail::filesystem::path const& path
, FormatTag const&
)
{
return make_scanline_reader( path.wstring()
, image_read_settings< FormatTag >()
);
}
#endif // BOOST_GIL_IO_ADD_FS_PATH_SUPPORT

template <typename Device, typename FormatTag>
inline
Expand Down
8 changes: 2 additions & 6 deletions include/boost/gil/io/make_writer.hpp
Expand Up @@ -60,21 +60,19 @@ make_writer( const std::wstring& file_name
);
}

#ifdef BOOST_GIL_IO_ADD_FS_PATH_SUPPORT
template< typename FormatTag >
inline
typename get_writer< std::wstring
, FormatTag
>::type
make_writer( const filesystem::path& path
make_writer( detail::filesystem::path const& path
, const image_write_info< FormatTag >& info
)
{
return make_writer( path.wstring()
, info
);
}
#endif // BOOST_GIL_IO_ADD_FS_PATH_SUPPORT

template <typename Device, typename FormatTag>
inline
Expand Down Expand Up @@ -125,21 +123,19 @@ make_writer( const std::wstring& file_name
);
}

#ifdef BOOST_GIL_IO_ADD_FS_PATH_SUPPORT
template< typename FormatTag >
inline
typename get_writer< std::wstring
, FormatTag
>::type
make_writer( const filesystem::path& path
make_writer( detail::filesystem::path const& path
, const FormatTag& tag
)
{
return make_writer( path.wstring()
, tag
);
}
#endif // BOOST_GIL_IO_ADD_FS_PATH_SUPPORT

template <typename Device, typename FormatTag>
inline
Expand Down
49 changes: 6 additions & 43 deletions include/boost/gil/io/path_spec.hpp
Expand Up @@ -8,29 +8,7 @@
#ifndef BOOST_GIL_IO_PATH_SPEC_HPP
#define BOOST_GIL_IO_PATH_SPEC_HPP

#ifdef BOOST_GIL_IO_ADD_FS_PATH_SUPPORT
// Disable warning: conversion to 'std::atomic<int>::__integral_type {aka int}' from 'long int' may alter its value
#if defined(BOOST_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
#endif

#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
#endif

#define BOOST_FILESYSTEM_VERSION 3
#include <boost/filesystem/path.hpp>

#if defined(BOOST_CLANG)
#pragma clang diagnostic pop
#endif

#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
#pragma GCC diagnostic pop
#endif
#endif // BOOST_GIL_IO_ADD_FS_PATH_SUPPORT
#include <boost/gil/io/detail/filesystem.hpp>

#include <cstdlib>
#include <string>
Expand All @@ -53,15 +31,8 @@ template<int i> struct is_supported_path_spec<char [i]> : std::true_
template<int i> struct is_supported_path_spec<const wchar_t [i]> : std::true_type {};
template<int i> struct is_supported_path_spec<wchar_t [i]> : std::true_type {};

#ifdef BOOST_GIL_IO_ADD_FS_PATH_SUPPORT
template<> struct is_supported_path_spec< filesystem::path > : std::true_type {};
template<> struct is_supported_path_spec< const filesystem::path > : std::true_type {};
#endif // BOOST_GIL_IO_ADD_FS_PATH_SUPPORT


///
/// convert_to_string
///
template<> struct is_supported_path_spec<filesystem::path> : std::true_type {};
template<> struct is_supported_path_spec<filesystem::path const> : std::true_type {};

inline std::string convert_to_string( std::string const& obj)
{
Expand All @@ -87,16 +58,10 @@ inline std::string convert_to_string( char* str )
return std::string( str );
}

#ifdef BOOST_GIL_IO_ADD_FS_PATH_SUPPORT
inline std::string convert_to_string( const filesystem::path& path )
inline std::string convert_to_string(filesystem::path const& path)
{
return convert_to_string( path.string() );
return convert_to_string(path.string());
}
#endif // BOOST_GIL_IO_ADD_FS_PATH_SUPPORT

///
/// convert_to_native_string
///

inline const char* convert_to_native_string( char* str )
{
Expand Down Expand Up @@ -131,8 +96,6 @@ inline const char* convert_to_native_string( const std::wstring& str )
return c;
}

} // namespace detail
} // namespace gil
} // namespace boost
}}} // namespace boost::gil::detail

#endif
4 changes: 1 addition & 3 deletions test/extension/io/bmp/bmp_make.cpp
Expand Up @@ -5,8 +5,6 @@
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#define BOOST_GIL_IO_ADD_FS_PATH_SUPPORT
#define BOOST_FILESYSTEM_VERSION 3
#include <boost/gil.hpp>
#include <boost/gil/extension/io/bmp.hpp>

Expand All @@ -22,7 +20,7 @@

#include "paths.hpp"

namespace fs = boost::filesystem;
namespace fs = boost::gil::detail::filesystem;
namespace gil = boost::gil;

void test_make_reader_backend()
Expand Down

0 comments on commit f4c70a8

Please sign in to comment.