//---------------------------------------------------------------------------// // Copyright (c) 2013 Kyle Lutz // // 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 // // See http://boostorg.github.com/compute for more information. //---------------------------------------------------------------------------// #ifndef BOOST_COMPUTE_CONTAINER_BASIC_STRING_HPP #define BOOST_COMPUTE_CONTAINER_BASIC_STRING_HPP #include #include #include #include #include #include #include #include #include namespace boost { namespace compute { /// \class basic_string /// \brief A template for a dynamically-sized character sequence. /// /// The \c basic_string class provides a generic template for a dynamically- /// sized character sequence. This is most commonly used through the \c string /// typedef (for \c basic_string). /// /// For example, to create a string on the device with its contents copied /// from a C-string on the host: /// \code /// boost::compute::string str("hello, world!"); /// \endcode /// /// \see \ref vector "vector" template > class basic_string { public: typedef Traits traits_type; typedef typename Traits::char_type value_type; typedef size_t size_type; static const size_type npos = size_type(-1); typedef typename ::boost::compute::vector::reference reference; typedef typename ::boost::compute::vector::const_reference const_reference; typedef typename ::boost::compute::vector::iterator iterator; typedef typename ::boost::compute::vector::const_iterator const_iterator; typedef typename ::boost::compute::vector::reverse_iterator reverse_iterator; typedef typename ::boost::compute::vector::const_reverse_iterator const_reverse_iterator; basic_string() { } basic_string(size_type count, CharT ch) : m_data(count) { std::fill(m_data.begin(), m_data.end(), ch); } basic_string(const basic_string &other, size_type pos, size_type count = npos) : m_data(other.begin() + pos, other.begin() + (std::min)(other.size(), count)) { } basic_string(const char *s, size_type count) : m_data(s, s + count) { } basic_string(const char *s) : m_data(s, s + std::strlen(s)) { } template basic_string(InputIterator first, InputIterator last) : m_data(first, last) { } basic_string(const basic_string &other) : m_data(other.m_data) { } basic_string& operator=(const basic_string &other) { if(this != &other){ m_data = other.m_data; } return *this; } ~basic_string() { } reference at(size_type pos) { return m_data.at(pos); } const_reference at(size_type pos) const { return m_data.at(pos); } reference operator[](size_type pos) { return m_data[pos]; } const_reference operator[](size_type pos) const { return m_data[pos]; } reference front() { return m_data.front(); } const_reference front() const { return m_data.front(); } reference back() { return m_data.back(); } const_reference back() const { return m_data.back(); } iterator begin() { return m_data.begin(); } const_iterator begin() const { return m_data.begin(); } const_iterator cbegin() const { return m_data.cbegin(); } iterator end() { return m_data.end(); } const_iterator end() const { return m_data.end(); } const_iterator cend() const { return m_data.cend(); } reverse_iterator rbegin() { return m_data.rbegin(); } const_reverse_iterator rbegin() const { return m_data.rbegin(); } const_reverse_iterator crbegin() const { return m_data.crbegin(); } reverse_iterator rend() { return m_data.rend(); } const_reverse_iterator rend() const { return m_data.rend(); } const_reverse_iterator crend() const { return m_data.crend(); } bool empty() const { return m_data.empty(); } size_type size() const { return m_data.size(); } size_type length() const { return m_data.size(); } size_type max_size() const { return m_data.max_size(); } void reserve(size_type size) { m_data.reserve(size); } size_type capacity() const { return m_data.capacity(); } void shrink_to_fit() { m_data.shrink_to_fit(); } void clear() { m_data.clear(); } void swap(basic_string &other) { if(this != &other) { ::boost::compute::vector temp_data(other.m_data); other.m_data = m_data; m_data = temp_data; } } basic_string substr(size_type pos = 0, size_type count = npos) const { return basic_string(*this, pos, count); } /// Finds the first character \p ch size_type find(CharT ch, size_type pos = 0) const { const_iterator iter = ::boost::compute::find(begin() + pos, end(), ch); if(iter == end()){ return npos; } else { return static_cast(std::distance(begin(), iter)); } } /// Finds the first substring equal to \p str size_type find(basic_string& str, size_type pos = 0) const { const_iterator iter = ::boost::compute::search(begin() + pos, end(), str.begin(), str.end()); if(iter == end()){ return npos; } else { return static_cast(std::distance(begin(), iter)); } } /// Finds the first substring equal to the character string /// pointed to by \p s. /// The length of the string is determined by the first null character. /// /// For example, the following code /// \snippet test/test_string.cpp string_find /// /// will return 5 as position. size_type find(const char* s, size_type pos = 0) const { basic_string str(s); const_iterator iter = ::boost::compute::search(begin() + pos, end(), str.begin(), str.end()); if(iter == end()){ return npos; } else { return static_cast(std::distance(begin(), iter)); } } private: ::boost::compute::vector m_data; }; template std::ostream& operator<<(std::ostream& stream, boost::compute::basic_stringconst& outStr) { command_queue queue = ::boost::compute::system::default_queue(); boost::compute::copy(outStr.begin(), outStr.end(), std::ostream_iterator(stream), queue); return stream; } } // end compute namespace } // end boost namespace #endif // BOOST_COMPUTE_CONTAINER_BASIC_STRING_HPP