<commit_before>// Copyright (C) 2012 iwg molw5
// For conditions of distribution and use, see copyright notice in COPYING

/**
* \file
* \brief Stream wrapper.
*
* \copyright
* Copyright &copy; 2012 iwg molw5<br>
* For conditions of distribution and use, see copyright notice in COPYING
*/

#pragma once

#include <functional>

namespace framework
{
    namespace serializable
    {
        /**
        * \headerfile stream_wrapper.hpp <framework/serializable/streams/stream_wrapper.hpp>
        * \brief Stream wrapper class.
        *
        * Provides the overrides necessary to forward read/write calls to an underlying stream.
        */
        template <typename Parent, typename Stream>
        class stream_wrapper : private std::reference_wrapper <Stream>
        {
            private:
                using base = std::reference_wrapper <Stream>;
                friend Parent;

            public:
                /**
                * \brief Wrapper constructor.
                *
                * \warn
                * The lifetime of stream must exceed this class; behaviour when this condition is not met is undefined.
                */
                stream_wrapper (Stream& stream)
                    : base(stream)
                {
                }

                /**
                * \brief Write forwarder.
                */
                template <typename T>
                auto write (T const& t) ->
                typename std::enable_if <write_type_exists <T, Stream>::value, bool>::type
                {
                    auto const parent_this = static_cast <Parent*> (this);
                    if (!parent_this->writepre(t))
                        return false;

                    if (!base::get().write(t))
                        return false;

                    if (!parent_this->writepost(t))
                        return false;

                    return true;
                }

                /**
                * \brief Write forwarder.
                */
                template <std::size_t N>
                auto write (char const* s) ->
                typename std::enable_if <write_count_exists <N, Stream>::value, bool>::type
                {
                    auto const parent_this = static_cast <Parent*> (this);
                    if (!parent_this->wrie_prefix(s))
                        return false;

                    if (!base::get().write <N> (s))
                        return false;

                    if (!parent_this->writepost(s))
                        return false;

                    return true;
                }

                /**
                * \brief Write forwarder.
                */
                template <typename... Args>
                auto write (Args&&... args) ->
                decltype(std::declval <Stream> ().write(args...), bool())
                {
                    auto const parent_this = static_cast <Parent*> (this);
                    if (!parent_this->writepre(args...))
                        return false;

                    if (!base::get().write(args...))
                        return false;

                    if (!parent_this->writepost(args...))
                        return false;

                    return true;
                }

                /**
                * \brief Read forwarder.
                */
                template <typename T>
                auto read (T const& t) ->
                typename std::enable_if <read_type_exists <Stream, T>::value, bool>::type
                {
                    auto const parent_this = static_cast <Parent*> (this);
                    if (!parent_this->readpre(t))
                        return false;

                    if (!base::get().read(t))
                        return false;

                    if (!parent_this->readpost(t))
                        return false;

                    return true;
                }

                /**
                * \brief Read forwarder.
                */
                template <std::size_t N>
                auto read (char const* s) ->
                typename std::enable_if <read_count_exists <Stream, N>::value, bool>::type
                {
                    auto const parent_this = static_cast <Parent*> (this);
                    if (!parent_this->wrie_prefix(s))
                        return false;

                    if (!base::get().read <N> (s))
                        return false;

                    if (!parent_this->readpost(s))
                        return false;

                    return true;
                }

                /**
                * \brief Read forwarder.
                */
                template <typename... Args>
                auto read (Args&&... args) ->
                decltype(std::declval <Stream> ().read(args...), bool())
                {
                    auto const parent_this = static_cast <Parent*> (this);
                    if (!parent_this->readpre(args...))
                        return false;

                    if (!base::get().read(args...))<commit_msg>- Bug fix; forwarders were too permisive<commit_after>// Copyright (C) 2012 iwg molw5
// For conditions of distribution and use, see copyright notice in COPYING

/**
* \file
* \brief Stream wrapper.
*
* \copyright
* Copyright &copy; 2012 iwg molw5<br>
* For conditions of distribution and use, see copyright notice in COPYING
*/

#pragma once

#include <functional>

namespace framework
{
    namespace serializable
    {
        namespace detail
        {
            template <typename... Args>
            struct extract_head_safe
            {
                using type = void;
            };

            template <typename Head, typename... Tail>
            struct extract_head_safe <Head, Tail...>
            {
                using type = Head;
            };
        }

        /**
        * \headerfile stream_wrapper.hpp <framework/serializable/streams/stream_wrapper.hpp>
        * \brief Stream wrapper class.
        *
        * Provides the overrides necessary to forward primitive read/write calls to an underlying stream.
        */
        template <typename Parent, typename Stream>
        class stream_wrapper : private std::reference_wrapper <Stream>
        {
            private:
                using base = std::reference_wrapper <Stream>;
                friend Parent;

            public:
                /**
                * \brief Wrapper constructor.
                *
                * \warn
                * The lifetime of stream must exceed this class; behaviour when this condition is not met is undefined.
                */
                stream_wrapper (Stream& stream)
                    : base(stream)
                {
                }

                /**
                * \brief Write forwarder.
                */
                template <typename T>
                auto write (T const& t) ->
                typename std::enable_if <write_type_exists <T, Stream>::value, bool>::type
                {
                    auto const parent_this = static_cast <Parent*> (this);
                    if (!parent_this->writepre(t))
                        return false;

                    if (!base::get().write(t))
                        return false;

                    if (!parent_this->writepost(t))
                        return false;

                    return true;
                }

                /**
                * \brief Write forwarder.
                */
                template <std::size_t N>
                auto write (char const* s) ->
                typename std::enable_if <write_count_exists <N, Stream>::value, bool>::type
                {
                    auto const parent_this = static_cast <Parent*> (this);
                    if (!parent_this->wrie_prefix(s))
                        return false;

                    if (!base::get().write <N> (s))
                        return false;

                    if (!parent_this->writepost(s))
                        return false;

                    return true;
                }

                /**
                * \brief Write forwarder.
                */
                template <typename... Args>
                auto write (Args&&... args) ->
                typename std::enable_if <
                    sizeof...(Args) != 1 ||
                    !write_type_exists <typename detail::extract_head_safe <Args...>::type, Stream>::value,
                    decltype(std::declval <Stream> ().write(args...), bool())
                >::type
                {
                    auto const parent_this = static_cast <Parent*> (this);
                    if (!parent_this->writepre(args...))
                        return false;

                    if (!base::get().write(args...))
                        return false;

                    if (!parent_this->writepost(args...))
                        return false;

                    return true;
                }

                /**
                * \brief Read forwarder.
                */
                template <typename T>
                auto read (T const& t) ->
                typename std::enable_if <read_type_exists <Stream, T>::value, bool>::type
                {
                    auto const parent_this = static_cast <Parent*> (this);
                    if (!parent_this->readpre(t))
                        return false;

                    if (!base::get().read(t))
                        return false;

                    if (!parent_this->readpost(t))
                        return false;

                    return true;
                }

                /**
                * \brief Read forwarder.
                */
                template <std::size_t N>
                auto read (char const* s) ->
                typename std::enable_if <read_count_exists <Stream, N>::value, bool>::type
                {
                    auto const parent_this = static_cast <Parent*> (this);
                    if (!parent_this->wrie_prefix(s))
                        return false;

                    if (!base::get().read <N> (s))
                        return false;

                    if (!parent_this->readpost(s))
                        return false;

                    return true;
                }

                /**
                * \brief Read forwarder.
                */
                template <typename... Args>
                auto read (Args&&... args) ->
                typename std::enable_if <
                    sizeof...(Args) != 1 ||
                    !read_type_exists <Stream, typename detail::extract_head_safe <Args...>::type>::value,
                    decltype(std::declval <Stream> ().read(args...), bool())
                >::type
                {
                    auto const parent_this = static_cast <Parent*> (this);
                    if (!parent_this->readpre(args...))
                        return false;

                    if (!base::get().read(args...))
{'fraction_non_alphanumeric': 0.10156813266041817, 'fraction_numerical': 0.0019826964671953856, 'mean_word_length': 1.0413907284768211, 'pattern_counts': {'":': 0, '<': 72, '<?xml version=': 0, '>': 106, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3514561', 'n_tokens_mistral': 2725, 'n_tokens_neox': 2430, 'n_words': 688}