/usr/include/boost/nowide
Edit: /usr/include/boost/nowide/fstream.hpp (14486B)
//
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
//
// Distributed under the Boost Software License, Version 1.0. (See
// 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
#include
#include
#include
namespace boost {
namespace nowide {
/// \cond INTERNAL
namespace detail {
// clang-format off
struct StreamTypeIn
{
static std::ios_base::openmode mode() { return std::ios_base::in; }
static std::ios_base::openmode mode_modifier() { return mode(); }
template
struct stream_base{
typedef std::basic_istream type;
};
};
struct StreamTypeOut
{
static std::ios_base::openmode mode() { return std::ios_base::out; }
static std::ios_base::openmode mode_modifier() { return mode(); }
template
struct stream_base{
typedef std::basic_ostream type;
};
};
struct StreamTypeInOut
{
static std::ios_base::openmode mode() { return std::ios_base::in | std::ios_base::out; }
static std::ios_base::openmode mode_modifier() { return std::ios_base::openmode(); }
template
struct stream_base{
typedef std::basic_iostream type;
};
};
// clang-format on
/// Base class for all basic_*fstream classes
/// Contains basic_filebuf instance so its pointer can be used to construct basic_*stream
/// Provides common functions to reduce boilerplate code including inheriting from
/// 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
/// \tparam FileBufType Discriminator to force a differing ABI if depending on the contained filebuf
template
class fstream_impl;
template
struct enable_if_path;
} // namespace detail
/// \endcond
///
/// \brief Same as std::basic_ifstream but accepts UTF-8 strings under Windows
///
template >
class basic_ifstream : public detail::fstream_impl
{
typedef detail::fstream_impl fstream_impl;
public:
basic_ifstream()
{}
explicit basic_ifstream(const char* file_name, std::ios_base::openmode mode = std::ios_base::in)
{
open(file_name, mode);
}
#if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
explicit basic_ifstream(const wchar_t* file_name, std::ios_base::openmode mode = std::ios_base::in)
{
open(file_name, mode);
}
#endif
explicit basic_ifstream(const std::string& file_name, std::ios_base::openmode mode = std::ios_base::in)
{
open(file_name, mode);
}
template
explicit basic_ifstream(
const Path& file_name,
typename detail::enable_if_path::type mode = std::ios_base::in)
{
open(file_name, mode);
}
using fstream_impl::open;
using fstream_impl::is_open;
using fstream_impl::close;
using fstream_impl::rdbuf;
using fstream_impl::swap;
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;
}
};
///
/// \brief Same as std::basic_ofstream but accepts UTF-8 strings under Windows
///
template >
class basic_ofstream : public detail::fstream_impl
{
typedef detail::fstream_impl fstream_impl;
public:
basic_ofstream()
{}
explicit basic_ofstream(const char* file_name, std::ios_base::openmode mode = std::ios_base::out)
{
open(file_name, mode);
}
#if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
explicit basic_ofstream(const wchar_t* file_name, std::ios_base::openmode mode = std::ios_base::out)
{
open(file_name, mode);
}
#endif
explicit basic_ofstream(const std::string& file_name, std::ios_base::openmode mode = std::ios_base::out)
{
open(file_name, mode);
}
template
explicit basic_ofstream(
const Path& file_name,
typename detail::enable_if_path::type mode = std::ios_base::out)
{
open(file_name, mode);
}
using fstream_impl::open;
using fstream_impl::is_open;
using fstream_impl::close;
using fstream_impl::rdbuf;
using fstream_impl::swap;
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;
}
};
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable : 4250) // : inherits via dominance
#endif
///
/// \brief Same as std::basic_fstream but accepts UTF-8 strings under Windows
///
template >
class basic_fstream : public detail::fstream_impl
{
typedef detail::fstream_impl fstream_impl;
public:
basic_fstream()
{}
explicit basic_fstream(const char* file_name,
std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
{
open(file_name, mode);
}
#if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
explicit basic_fstream(const wchar_t* file_name,
std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
{
open(file_name, mode);
}
#endif
explicit basic_fstream(const std::string& file_name,
std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
{
open(file_name, mode);
}
template
explicit basic_fstream(const Path& file_name,
typename detail::enable_if_path::type mode =
std::ios_base::in | std::ios_base::out)
{
open(file_name, mode);
}
using fstream_impl::open;
using fstream_impl::is_open;
using fstream_impl::close;
using fstream_impl::rdbuf;
using fstream_impl::swap;
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;
}
};
template
void swap(basic_filebuf& lhs, basic_filebuf& rhs)
{
lhs.swap(rhs);
}
template
void swap(basic_ifstream& lhs, basic_ifstream& rhs)
{
lhs.swap(rhs);
}
template
void swap(basic_ofstream& lhs, basic_ofstream& rhs)
{
lhs.swap(rhs);
}
template
void swap(basic_fstream& lhs, basic_fstream& rhs)
{
lhs.swap(rhs);
}
///
/// Same as std::filebuf but accepts UTF-8 strings under Windows
///
typedef basic_filebuf filebuf;
///
/// Same as std::ifstream but accepts UTF-8 strings under Windows
/// and *\::filesystem::path on all systems
///
typedef basic_ifstream ifstream;
///
/// Same as std::ofstream but accepts UTF-8 strings under Windows
/// and *\::filesystem::path on all systems
///
typedef basic_ofstream ofstream;
///
/// Same as std::fstream but accepts UTF-8 strings under Windows
/// and *\::filesystem::path on all systems
///
typedef basic_fstream fstream;
// Implementation
namespace detail {
/// Holds an instance of T
/// Required to make sure this is constructed first before passing it to sibling classes
template
struct buf_holder
{
T buf_;
};
template
class fstream_impl : private buf_holder >, // must be first due to init order
public T_StreamType::template stream_base::type
{
typedef basic_filebuf internal_buffer_type;
typedef buf_holder base_buf_holder;
typedef typename T_StreamType::template stream_base::type stream_base;
public:
using stream_base::setstate;
using stream_base::clear;
protected:
using base_buf_holder::buf_;
fstream_impl() : stream_base(&buf_)
{}
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))
{
this->set_rdbuf(rdbuf());
}
fstream_impl& operator=(fstream_impl&& rhs) noexcept
{
base_buf_holder::operator=(std::move(rhs));
stream_base::operator=(std::move(rhs));
return *this;
}
void swap(fstream_impl& other)
{
stream_base::swap(other);
rdbuf()->swap(*other.rdbuf());
}
void open(const std::string& file_name, std::ios_base::openmode mode = T_StreamType::mode())
{
open(file_name.c_str(), mode);
}
template
typename detail::enable_if_path::type open(const Path& file_name,
std::ios_base::openmode mode = T_StreamType::mode())
{
open(file_name.c_str(), mode);
}
void open(const char* file_name, std::ios_base::openmode mode = T_StreamType::mode())
{
if(!rdbuf()->open(file_name, mode | T_StreamType::mode_modifier()))
setstate(std::ios_base::failbit);
else
clear();
}
#if BOOST_NOWIDE_USE_WCHAR_OVERLOADS
void open(const wchar_t* file_name, std::ios_base::openmode mode = T_StreamType::mode())
{
if(!rdbuf()->open(file_name, mode | T_StreamType::mode_modifier()))
setstate(std::ios_base::failbit);
else
clear();
}
#endif
bool is_open()
{
return rdbuf()->is_open();
}
bool is_open() const
{
return rdbuf()->is_open();
}
void close()
{
if(!rdbuf()->close())
setstate(std::ios_base::failbit);
}
internal_buffer_type* rdbuf() const
{
return const_cast(&buf_);
}
};
#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
struct is_path
{
typedef char one;
struct two
{
char dummy[2];
};
template
struct Check;
template
static one test(Check*);
template
static two test(...);
enum
{
value = sizeof(test(0)) == sizeof(one)
};
};
template
struct enable_if
{};
template
struct enable_if
{
typedef T type;
};
/// SFINAE trait which has a member "type = Result" if the Path is a *\::filesystem::path
template
struct enable_if_path : enable_if::value, Result>
{};
} // namespace detail
} // namespace nowide
} // namespace boost
#endif