Информация об изменениях

Сообщение Re: imploder от 19.06.2023 23:09

Изменено 19.06.2023 23:12 Sm0ke

Re: imploder
Здравствуйте, пффф, Вы писали:

П>Привет!


Я бы назвал такой класс impoder
В честь функции implode() из php (обратное от explode() aka split)

gbolt: https://godbolt.org/z/dKvePffc4

// Имплементация:

#include <concepts>
#include <sstream>
#include <string>
#include <cstdint>

enum class empty_kind { skip, accept };

template <empty_kind Empty_kind>
class imploder {
    // data
    std::stringstream
        m_stream;
    std::string
        m_separator;
    std::uintptr_t
        m_length{0};

public:
    using t_text = const std::string &;

    imploder(t_text p_separator) : m_separator{p_separator} {}

    void append(t_text p_str) {
        if constexpr ( Empty_kind == empty_kind::skip ) {
            if( p_str.empty() ) { return; }
        }
        if( m_length > 0 ) {
            m_stream << m_separator;
            m_length += m_separator.length();
        }
        m_stream << p_str;
         m_length += p_str.length();
    }

    template <std::same_as<std::string> ... Args>
    void append(const Args & ... p_items) {
        (append(p_items), ...);
    }

    template <typename Container>
    void append_range(const Container & p_items) {
        for( typename Container::const_reference v_it : p_items ) {
            append(v_it);
        }
    }

    std::string result() const { return m_stream.str(); }
};

// Использование:

#include <vector>
#include <iostream>

int main() {
    using namespace std::string_literals;
    
    // imploder<empty_kind::accept> v_imp{", "s};
    imploder<empty_kind::skip> v_imp{", "s};
    v_imp.append("a"s, "b"s, ""s, "c"s);

    std::vector<std::string> v_vec{"d"s, ""s, "e"s, "f"s};
    v_imp.append_range(v_vec);

    std::cout << v_imp.result() << '\n';
    return 0;
}
Re: imploder
Здравствуйте, пффф, Вы писали:

П>Привет!


Я бы назвал такой класс impoder
В честь функции implode() из php (обратное от explode() aka split)

gbolt: https://godbolt.org/z/dKvePffc4

// Имплементация:

#include <concepts>
#include <sstream>
#include <string>
#include <cstdint>

enum class empty_kind { skip, accept };

template <empty_kind Empty_kind>
class imploder {
    // data
    std::stringstream
        m_stream;
    std::string
        m_separator;
    std::uintptr_t
        m_length{0};

public:
    using t_text = const std::string &;

    imploder(t_text p_separator) : m_separator{p_separator} {}

    void append(t_text p_str) {
        if constexpr ( Empty_kind == empty_kind::skip ) {
            if( p_str.empty() ) { return; }
        }
        if( m_length > 0 ) {
            m_stream << m_separator;
            m_length += m_separator.length();
        }
        m_stream << p_str;
        m_length += p_str.length();
    }

    template <std::same_as<std::string> ... Args>
    void append(const Args & ... p_items) {
        (append(p_items), ...);
    }

    template <typename Container>
    void append_range(const Container & p_items) {
        for( typename Container::const_reference v_it : p_items ) {
            append(v_it);
        }
    }

    std::string result() const { return m_stream.str(); }
};

// Использование:

#include <vector>
#include <iostream>

int main() {
    using namespace std::string_literals;
    
    // imploder<empty_kind::accept> v_imp{", "s};
    imploder<empty_kind::skip> v_imp{", "s};
    v_imp.append("a"s, "b"s, ""s, "c"s);

    std::vector<std::string> v_vec{"d"s, ""s, "e"s, "f"s};
    v_imp.append_range(v_vec);

    std::cout << v_imp.result() << '\n';
    return 0;
}