// Copyright (c) 2012 Artyom Beilis (Tonkikh)
//
// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
+// accompanying file LICENSE or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_NOWIDE_FSTREAM_HPP_INCLUDED
#define BOOST_NOWIDE_FSTREAM_HPP_INCLUDED
#include <boost/nowide/config.hpp>
+#include <boost/nowide/detail/is_path.hpp>
#include <boost/nowide/filebuf.hpp>
#include <istream>
#include <ostream>
+#include <utility>
namespace boost {
namespace nowide {
static std::ios_base::openmode mode_modifier() { return mode(); }
template<typename CharType, typename Traits>
struct stream_base{
- typedef std::basic_istream<CharType, Traits> type;
+ using type = std::basic_istream<CharType, Traits>;
};
};
struct StreamTypeOut
static std::ios_base::openmode mode_modifier() { return mode(); }
template<typename CharType, typename Traits>
struct stream_base{
- typedef std::basic_ostream<CharType, Traits> type;
+ using type = std::basic_ostream<CharType, Traits>;
};
};
struct StreamTypeInOut
static std::ios_base::openmode mode_modifier() { return std::ios_base::openmode(); }
template<typename CharType, typename Traits>
struct stream_base{
- typedef std::basic_iostream<CharType, Traits> type;
+ using type = std::basic_iostream<CharType, Traits>;
};
};
// clang-format on
/// the correct std::basic_[io]stream class and initializing it
/// \tparam T_StreamType One of StreamType* above.
/// Class used instead of value, because openmode::operator| may not be constexpr
- template<typename CharType, typename Traits, typename T_StreamType>
+ /// \tparam FileBufType Discriminator to force a differing ABI if depending on the contained filebuf
+ template<typename CharType,
+ typename Traits,
+ typename T_StreamType,
+ int FileBufType = BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT>
class fstream_impl;
- template<typename Path, typename Result>
- struct enable_if_path;
} // namespace detail
/// \endcond
///
/// \brief Same as std::basic_ifstream<char> but accepts UTF-8 strings under Windows
///
- template<typename CharType, typename Traits = std::char_traits<CharType> >
+ template<typename CharType, typename Traits = std::char_traits<CharType>>
class basic_ifstream : public detail::fstream_impl<CharType, Traits, detail::StreamTypeIn>
{
- typedef detail::fstream_impl<CharType, Traits, detail::StreamTypeIn> fstream_impl;
+ using fstream_impl = detail::fstream_impl<CharType, Traits, detail::StreamTypeIn>;
public:
basic_ifstream()
}
template<typename Path>
- explicit basic_ifstream(
- const Path& file_name,
- typename detail::enable_if_path<Path, std::ios_base::openmode>::type mode = std::ios_base::in)
+ explicit basic_ifstream(const Path& file_name,
+ detail::enable_if_path_t<Path, std::ios_base::openmode> mode = std::ios_base::in)
{
open(file_name, mode);
}
using fstream_impl::is_open;
using fstream_impl::close;
using fstream_impl::rdbuf;
-#if BOOST_NOWIDE_CXX11
using fstream_impl::swap;
- basic_ifstream(const basic_ifstream& other) = delete;
- basic_ifstream& operator=(const basic_ifstream& rhs) = delete;
+ basic_ifstream(const basic_ifstream&) = delete;
+ basic_ifstream& operator=(const basic_ifstream&) = delete;
basic_ifstream(basic_ifstream&& other) noexcept : fstream_impl(std::move(other))
{}
basic_ifstream& operator=(basic_ifstream&& rhs) noexcept
fstream_impl::operator=(std::move(rhs));
return *this;
}
-#endif
};
///
/// \brief Same as std::basic_ofstream<char> but accepts UTF-8 strings under Windows
///
- template<typename CharType, typename Traits = std::char_traits<CharType> >
+ template<typename CharType, typename Traits = std::char_traits<CharType>>
class basic_ofstream : public detail::fstream_impl<CharType, Traits, detail::StreamTypeOut>
{
- typedef detail::fstream_impl<CharType, Traits, detail::StreamTypeOut> fstream_impl;
+ using fstream_impl = detail::fstream_impl<CharType, Traits, detail::StreamTypeOut>;
public:
basic_ofstream()
open(file_name, mode);
}
template<typename Path>
- explicit basic_ofstream(
- const Path& file_name,
- typename detail::enable_if_path<Path, std::ios_base::openmode>::type mode = std::ios_base::out)
+ explicit basic_ofstream(const Path& file_name,
+ detail::enable_if_path_t<Path, std::ios_base::openmode> mode = std::ios_base::out)
{
open(file_name, mode);
}
using fstream_impl::is_open;
using fstream_impl::close;
using fstream_impl::rdbuf;
-#if BOOST_NOWIDE_CXX11
using fstream_impl::swap;
- basic_ofstream(const basic_ofstream& other) = delete;
- basic_ofstream& operator=(const basic_ofstream& rhs) = delete;
+ basic_ofstream(const basic_ofstream&) = delete;
+ basic_ofstream& operator=(const basic_ofstream&) = delete;
basic_ofstream(basic_ofstream&& other) noexcept : fstream_impl(std::move(other))
{}
basic_ofstream& operator=(basic_ofstream&& rhs)
fstream_impl::operator=(std::move(rhs));
return *this;
}
-#endif
};
#ifdef BOOST_MSVC
///
/// \brief Same as std::basic_fstream<char> but accepts UTF-8 strings under Windows
///
- template<typename CharType, typename Traits = std::char_traits<CharType> >
+ template<typename CharType, typename Traits = std::char_traits<CharType>>
class basic_fstream : public detail::fstream_impl<CharType, Traits, detail::StreamTypeInOut>
{
- typedef detail::fstream_impl<CharType, Traits, detail::StreamTypeInOut> fstream_impl;
+ using fstream_impl = detail::fstream_impl<CharType, Traits, detail::StreamTypeInOut>;
public:
basic_fstream()
}
template<typename Path>
explicit basic_fstream(const Path& file_name,
- typename detail::enable_if_path<Path, std::ios_base::openmode>::type mode =
- std::ios_base::in | std::ios_base::out)
+ detail::enable_if_path_t<Path, std::ios_base::openmode> mode = std::ios_base::in
+ | std::ios_base::out)
{
open(file_name, mode);
}
using fstream_impl::is_open;
using fstream_impl::close;
using fstream_impl::rdbuf;
-#if BOOST_NOWIDE_CXX11
using fstream_impl::swap;
- basic_fstream(const basic_fstream& other) = delete;
- basic_fstream& operator=(const basic_fstream& rhs) = delete;
+ basic_fstream(const basic_fstream&) = delete;
+ basic_fstream& operator=(const basic_fstream&) = delete;
basic_fstream(basic_fstream&& other) noexcept : fstream_impl(std::move(other))
{}
basic_fstream& operator=(basic_fstream&& rhs)
fstream_impl::operator=(std::move(rhs));
return *this;
}
-#endif
};
-#if BOOST_NOWIDE_CXX11
template<typename CharType, typename Traits>
void swap(basic_filebuf<CharType, Traits>& lhs, basic_filebuf<CharType, Traits>& rhs)
{
{
lhs.swap(rhs);
}
-#endif
///
/// Same as std::filebuf but accepts UTF-8 strings under Windows
///
- typedef basic_filebuf<char> filebuf;
+ using filebuf = basic_filebuf<char>;
///
/// Same as std::ifstream but accepts UTF-8 strings under Windows
/// and *\::filesystem::path on all systems
///
- typedef basic_ifstream<char> ifstream;
+ using ifstream = basic_ifstream<char>;
///
/// Same as std::ofstream but accepts UTF-8 strings under Windows
/// and *\::filesystem::path on all systems
///
- typedef basic_ofstream<char> ofstream;
+ using ofstream = basic_ofstream<char>;
///
/// Same as std::fstream but accepts UTF-8 strings under Windows
/// and *\::filesystem::path on all systems
///
- typedef basic_fstream<char> fstream;
+ using fstream = basic_fstream<char>;
// Implementation
namespace detail {
{
T buf_;
};
- template<typename CharType, typename Traits, typename T_StreamType>
- class fstream_impl : private buf_holder<basic_filebuf<CharType, Traits> >, // must be first due to init order
+ template<typename CharType, typename Traits, typename T_StreamType, int>
+ class fstream_impl : private buf_holder<basic_filebuf<CharType, Traits>>, // must be first due to init order
public T_StreamType::template stream_base<CharType, Traits>::type
{
- typedef basic_filebuf<CharType, Traits> internal_buffer_type;
- typedef buf_holder<internal_buffer_type> base_buf_holder;
- typedef typename T_StreamType::template stream_base<CharType, Traits>::type stream_base;
+ using internal_buffer_type = basic_filebuf<CharType, Traits>;
+ using base_buf_holder = buf_holder<internal_buffer_type>;
+ using stream_base = typename T_StreamType::template stream_base<CharType, Traits>::type;
public:
using stream_base::setstate;
fstream_impl() : stream_base(&buf_)
{}
-
-#if BOOST_NOWIDE_CXX11
- fstream_impl(const fstream_impl& other) = delete;
- fstream_impl& operator=(const fstream_impl& other) = delete;
+ fstream_impl(const fstream_impl&) = delete;
+ fstream_impl& operator=(const fstream_impl&) = delete;
// coverity[exn_spec_violation]
- fstream_impl(fstream_impl&& other) noexcept : base_buf_holder(std::move(other)),
- stream_base(std::move(other))
+ fstream_impl(fstream_impl&& other) noexcept :
+ base_buf_holder(std::move(other)), stream_base(std::move(other))
{
this->set_rdbuf(rdbuf());
}
stream_base::swap(other);
rdbuf()->swap(*other.rdbuf());
}
-#endif
void open(const std::string& file_name, std::ios_base::openmode mode = T_StreamType::mode())
{
open(file_name.c_str(), mode);
}
template<typename Path>
- typename detail::enable_if_path<Path, void>::type open(const Path& file_name,
- std::ios_base::openmode mode = T_StreamType::mode())
+ detail::enable_if_path_t<Path, void> open(const Path& file_name,
+ std::ios_base::openmode mode = T_StreamType::mode())
{
open(file_name.c_str(), mode);
}
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
- /// Trait to heuristically check for a *\::filesystem::path
- /// Done by checking for make_preferred and filename member functions with correct signature
- template<typename T>
- struct is_path
- {
- typedef char one;
- struct two
- {
- char dummy[2];
- };
-
- template<typename U, U& (U::*)(), U (U::*)() const>
- struct Check;
- template<typename U>
- static one test(Check<U, &U::make_preferred, &U::filename>*);
- template<typename U>
- static two test(...);
-
- enum
- {
- value = sizeof(test<T>(0)) == sizeof(one)
- };
- };
- template<bool B, typename T>
- struct enable_if
- {};
- template<typename T>
- struct enable_if<true, T>
- {
- typedef T type;
- };
- /// SFINAE trait which has a member "type = Result" if the Path is a *\::filesystem::path
- template<typename Path, typename Result>
- struct enable_if_path : enable_if<is_path<Path>::value, Result>
- {};
} // namespace detail
} // namespace nowide
} // namespace boost