/strtk.hpp
C++ Header | 13496 lines | 12692 code | 752 blank | 52 comment | 847 complexity | 0a8accbcd9730aa9e8c7743f9e912017 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- /*
- *****************************************************************
- * String Toolkit Library *
- * *
- * Author: Arash Partow (2002-2013) *
- * URL: http://www.partow.net/programming/strtk/index.html *
- * *
- * Copyright notice: *
- * Free use of the String Toolkit Library is permitted under the *
- * guidelines and in accordance with the most current version of *
- * the Common Public License. *
- * http://www.opensource.org/licenses/cpl1.0.php *
- * *
- *****************************************************************
- */
- #ifndef INCLUDE_STRTK_HPP
- #define INCLUDE_STRTK_HPP
- #include <cstddef>
- #include <cctype>
- #include <cstring>
- #include <cerrno>
- #include <exception>
- #include <cmath>
- #include <iterator>
- #include <limits>
- #include <iostream>
- #include <fstream>
- #include <sstream>
- #include <utility>
- #include <algorithm>
- #include <string>
- #include <vector>
- #include <deque>
- #include <list>
- #include <set>
- #include <map>
- #include <stack>
- #include <queue>
- #ifndef strtk_no_tr1_or_boost
- #define strtk_enable_lexical_cast
- #define strtk_enable_random
- #define strtk_enable_regex
- #endif
- #ifdef strtk_enable_lexical_cast
- #include <boost/lexical_cast.hpp>
- #endif
- #ifdef strtk_enable_random
- // Requires definition of a TR1 compatible random library header
- //#include <random>
- #include <boost/random.hpp>
- #endif
- #ifdef strtk_enable_regex
- // Requires definition of a TR1 compatible regex library header
- //#include <regex>
- #include <boost/regex.hpp>
- #endif
- namespace strtk
- {
- static const std::size_t one_kilobyte = 1024;
- static const std::size_t one_megabyte = 1024 * one_kilobyte;
- static const std::size_t one_gigabyte = 1024 * one_megabyte;
- static const std::size_t magic_seed = 0xA5A5A5A5;
- template <typename Tokenizer, typename Function>
- inline std::size_t for_each_token(const std::string& buffer,
- Tokenizer& tokenizer,
- Function function)
- {
- std::size_t token_count = 0;
- tokenizer.assign(buffer);
- typename Tokenizer::iterator itr = tokenizer.begin();
- typename Tokenizer::const_iterator end = tokenizer.end();
- while (end != itr)
- {
- function(*itr);
- ++itr;
- ++token_count;
- }
- return token_count;
- }
- template <typename Function>
- inline std::size_t for_each_line(std::istream& stream,
- Function function,
- const std::size_t& buffer_size = one_kilobyte)
- {
- std::string buffer;
- buffer.reserve(buffer_size);
- std::size_t line_count = 0;
- while (std::getline(stream,buffer))
- {
- function(buffer);
- ++line_count;
- }
- return line_count;
- }
- template <typename Function>
- inline std::size_t for_each_line_n(std::istream& stream,
- const std::size_t& n,
- Function function,
- const std::size_t& buffer_size = one_kilobyte)
- {
- std::string buffer;
- buffer.reserve(buffer_size);
- std::size_t line_count = 0;
- while (std::getline(stream,buffer))
- {
- function(buffer);
- if (n == ++line_count)
- break;
- }
- return line_count;
- }
- template <typename Function>
- inline std::size_t for_each_line(const std::string& file_name,
- Function function,
- const std::size_t& buffer_size = one_kilobyte)
- {
- std::ifstream stream(file_name.c_str());
- if (stream)
- return for_each_line(stream,function,buffer_size);
- else
- return 0;
- }
- template <typename Function>
- inline std::size_t for_each_line_n(const std::string& file_name,
- const std::size_t& n,
- Function function,
- const std::size_t& buffer_size = one_kilobyte)
- {
- std::ifstream stream(file_name.c_str());
- if (stream)
- return for_each_line_n(stream,n,function,buffer_size);
- else
- return 0;
- }
- template <typename Function>
- inline std::size_t for_each_line_conditional(std::istream& stream,
- Function function,
- const std::size_t& buffer_size = one_kilobyte)
- {
- std::string buffer;
- buffer.reserve(buffer_size);
- std::size_t line_count = 0;
- while (std::getline(stream,buffer))
- {
- if (!function(buffer))
- {
- return line_count;
- }
- ++line_count;
- }
- return line_count;
- }
- template <typename Function>
- inline std::size_t for_each_line_n_conditional(std::istream& stream,
- const std::size_t& n,
- Function function,
- const std::size_t& buffer_size = one_kilobyte)
- {
- std::string buffer;
- buffer.reserve(buffer_size);
- std::size_t line_count = 0;
- while (std::getline(stream,buffer))
- {
- if (!function(buffer))
- {
- return line_count;
- }
- if (n == ++line_count)
- break;
- }
- return line_count;
- }
- template <typename Function>
- inline std::size_t for_each_line_conditional(const std::string& file_name,
- Function function,
- const std::size_t& buffer_size = one_kilobyte)
- {
- std::ifstream stream(file_name.c_str());
- if (stream)
- return for_each_line_conditional(stream,function,buffer_size);
- else
- return 0;
- }
- template <typename Function>
- inline std::size_t for_each_line_n_conditional(const std::string& file_name,
- const std::size_t& n,
- Function function,
- const std::size_t& buffer_size = one_kilobyte)
- {
- std::ifstream stream(file_name.c_str());
- if (stream)
- return for_each_line_n_conditional(stream,n,function,buffer_size);
- else
- return 0;
- }
- template <typename T>
- inline bool read_line_as_value(std::istream& stream,
- T& t,
- const std::size_t& buffer_size = one_kilobyte)
- {
- std::string buffer;
- buffer.reserve(buffer_size);
- if (!std::getline(stream,buffer))
- return false;
- return string_to_type_converter(buffer,t);
- }
- namespace details
- {
- struct not_supported_type_tag {};
- struct unsigned_type_tag {};
- struct signed_type_tag {};
- struct real_type_tag {};
- struct byte_type_tag {};
- struct bool_type_tag {};
- struct hex_number_type_tag {};
- struct hex_string_type_tag {};
- struct base64_type_tag {};
- struct ignore_token_type_tag {};
- struct stdstring_type_tag {};
- struct stdstring_range_type_tag {};
- struct value_type_tag {};
- struct sink_type_tag {};
- struct stl_seq_type_tag {};
- struct attribute_type_tag {};
- struct semantic_action_type_tag {};
- struct expect_type_tag {};
- struct like_type_tag {};
- struct inrange_type_tag {};
- struct trim_type_tag {};
- struct lcase_type_tag {};
- struct ucase_type_tag {};
- struct fillchararray_type_tag {};
- template <typename T>
- struct supported_conversion_to_type
- {
- typedef not_supported_type_tag type;
- };
- template <typename T>
- struct supported_conversion_from_type
- {
- typedef not_supported_type_tag type;
- };
- template <bool, typename T = void>
- struct enable_if {};
- template <typename T>
- struct enable_if<true, T> { typedef T type; };
- template <typename T>
- struct supported_iterator_type
- {
- enum { value = false };
- };
- template <typename T>
- struct is_valid_iterator
- {
- typedef typename details::enable_if<details::supported_iterator_type<T>::value,T>::type type;
- };
- template <typename T> struct numeric;
- template <typename T> inline std::size_t type_length(const T&);
- struct no_t {};
- struct yes_t {};
- template <typename T>
- struct is_pod
- {
- typedef no_t result_t;
- enum { result = false };
- };
- template <typename T>
- struct is_stl_container
- { typedef no_t result_t; };
- #define register_stl_container1(C) \
- template <typename T1, typename T2>struct is_stl_container<C<T1,T2> >{ typedef yes_t result_t; };
- #define register_stl_container2(C) \
- template <typename T1, typename T2, typename T3>struct is_stl_container<C<T1,T2,T3> >{ typedef yes_t result_t; };
- register_stl_container1(std::vector)
- register_stl_container1(std::deque)
- register_stl_container1(std::list)
- register_stl_container1(std::queue)
- register_stl_container1(std::stack)
- register_stl_container2(std::set)
- register_stl_container2(std::multiset)
- register_stl_container2(std::priority_queue)
- #undef register_stl_container1
- #undef register_stl_container2
- } // namespace details
- template <typename Iterator, typename T>
- inline bool string_to_type_converter(const Iterator begin, const Iterator end, T& t)
- {
- typedef typename details::is_valid_iterator<Iterator>::type itr_type;
- typename details::supported_conversion_to_type<T>::type type;
- Iterator itr = begin;
- return string_to_type_converter_impl(itr,end,t,type);
- }
- template <typename Iterator, typename T>
- inline bool string_to_type_converter(const std::pair<Iterator,Iterator>& range, T& t)
- {
- return string_to_type_converter(range.first,range.second,t);
- }
- template <typename T, typename Iterator>
- inline T string_to_type_converter(const Iterator begin, const Iterator end)
- {
- typedef typename details::is_valid_iterator<Iterator>::type itr_type;
- typename details::supported_conversion_to_type<T>::type type;
- T t;
- Iterator itr = begin;
- if (string_to_type_converter_impl(itr,end,t,type))
- return t;
- else
- throw std::invalid_argument("string_to_type_converter() - Failed to convert: " +
- std::string(begin,end));
- }
- template <typename T, typename Iterator>
- inline T string_to_type_converter(const std::pair<Iterator,Iterator>& range)
- {
- return string_to_type_converter<T>(range.first,range.second);
- }
- template <typename T>
- inline bool string_to_type_converter(const std::string& s, T& t)
- {
- return string_to_type_converter<const char*,T>(s.data(),s.data() + s.size(),t);
- }
- template <typename T>
- inline T string_to_type_converter(const std::string& s)
- {
- return string_to_type_converter<T>(s.data(),s.data() + s.size());
- }
- template <typename T>
- inline bool type_to_string(const T& t, std::string& s)
- {
- typename details::supported_conversion_from_type<T>::type type;
- return type_to_string_converter_impl(t,s,type);
- }
- template <typename T>
- inline std::string type_to_string(const T& t)
- {
- std::string s;
- if (type_to_string<T>(t,s))
- return s;
- else
- throw std::invalid_argument("type_to_string() - Failed to convert type to string");
- }
- #define strtk_begin_register_string_to_type \
- namespace strtk { namespace details {
- #define strtk_end_register_string_to_type \
- }}
- #define strtk_string_to_type_begin(Type) \
- namespace strtk { namespace details { template <typename Iterator> \
- inline bool string_to_type_converter_impl(const Iterator& begin, const Iterator& end, \
- Type& t, details::not_supported_type_tag&) {
- #define strtk_string_to_type_end()\
- }}}
- template <typename T,
- typename Allocator,
- template <typename,typename> class Sequence>
- inline std::size_t load_from_text_file(std::istream& stream,
- Sequence<T,Allocator>& sequence,
- const std::size_t& buffer_size = one_kilobyte)
- {
- if (!stream) return 0;
- std::string buffer;
- buffer.reserve(buffer_size);
- std::size_t line_count = 0;
- while (std::getline(stream,buffer))
- {
- ++line_count;
- sequence.push_back(string_to_type_converter<T>(buffer));
- }
- return line_count;
- }
- template <typename T,
- typename Comparator,
- typename Allocator>
- inline std::size_t load_from_text_file(std::istream& stream,
- std::set<T,Comparator,Allocator>& set,
- const std::size_t& buffer_size = one_kilobyte)
- {
- if (!stream) return 0;
- std::string buffer;
- buffer.reserve(buffer_size);
- std::size_t line_count = 0;
- while (std::getline(stream,buffer))
- {
- ++line_count;
- set.insert(string_to_type_converter<T>(buffer));
- }
- return line_count;
- }
- template <typename T,
- typename Comparator,
- typename Allocator>
- inline std::size_t load_from_text_file(std::istream& stream,
- std::multiset<T,Comparator,Allocator>& multiset,
- const std::size_t& buffer_size = one_kilobyte)
- {
- if (!stream) return 0;
- std::string buffer;
- buffer.reserve(buffer_size);
- std::size_t line_count = 0;
- while (std::getline(stream,buffer))
- {
- ++line_count;
- multiset.insert(string_to_type_converter<T>(buffer));
- }
- return line_count;
- }
- template <typename T, typename Container>
- inline std::size_t load_from_text_file(std::istream& stream,
- std::queue<T,Container>& queue,
- const std::size_t& buffer_size = one_kilobyte)
- {
- if (!stream) return 0;
- std::string buffer;
- buffer.reserve(buffer_size);
- std::size_t line_count = 0;
- while (std::getline(stream,buffer))
- {
- ++line_count;
- queue.push(string_to_type_converter<T>(buffer));
- }
- return line_count;
- }
- template <typename T, typename Container>
- inline std::size_t load_from_text_file(std::istream& stream,
- std::stack<T,Container>& stack,
- const std::size_t& buffer_size = one_kilobyte)
- {
- if (!stream) return 0;
- std::string buffer;
- buffer.reserve(buffer_size);
- std::size_t line_count = 0;
- while (std::getline(stream,buffer))
- {
- ++line_count;
- stack.push(string_to_type_converter<T>(buffer));
- }
- return line_count;
- }
- template <typename T,
- typename Container,
- typename Comparator>
- inline std::size_t load_from_text_file(std::istream& stream,
- std::priority_queue<T,Container,Comparator>& priority_queue,
- const std::size_t& buffer_size = one_kilobyte)
- {
- if (!stream) return 0;
- std::string buffer;
- buffer.reserve(buffer_size);
- std::size_t line_count = 0;
- while (std::getline(stream,buffer))
- {
- ++line_count;
- priority_queue.push(string_to_type_converter<T>(buffer));
- }
- return line_count;
- }
- template <typename T,
- typename Allocator,
- template <typename,typename> class Sequence>
- inline std::size_t load_from_text_file(const std::string& file_name,
- Sequence<T,Allocator>& sequence,
- const std::size_t& buffer_size = one_kilobyte)
- {
- std::ifstream stream(file_name.c_str());
- if (!stream)
- return 0;
- else
- return load_from_text_file(stream,sequence,buffer_size);
- }
- template <typename T,
- typename Comparator,
- typename Allocator>
- inline std::size_t load_from_text_file(const std::string& file_name,
- std::set<T,Comparator,Allocator>& set,
- const std::size_t& buffer_size = one_kilobyte)
- {
- std::ifstream stream(file_name.c_str());
- if (!stream)
- return 0;
- else
- return load_from_text_file(stream,set,buffer_size);
- }
- template <typename T,
- typename Comparator,
- typename Allocator>
- inline std::size_t load_from_text_file(const std::string& file_name,
- std::multiset<T,Comparator,Allocator>& multiset,
- const std::size_t& buffer_size = one_kilobyte)
- {
- std::ifstream stream(file_name.c_str());
- if (!stream)
- return 0;
- else
- return load_from_text_file(stream,multiset,buffer_size);
- }
- template <typename T, typename Container>
- inline std::size_t load_from_text_file(const std::string& file_name,
- std::queue<T,Container>& queue,
- const std::size_t& buffer_size = one_kilobyte)
- {
- std::ifstream stream(file_name.c_str());
- if (!stream)
- return 0;
- else
- return load_from_text_file(stream,queue,buffer_size);
- }
- template <typename T, typename Container>
- inline std::size_t load_from_text_file(const std::string& file_name,
- std::stack<T,Container>& stack,
- const std::size_t& buffer_size = one_kilobyte)
- {
- std::ifstream stream(file_name.c_str());
- if (!stream)
- return 0;
- else
- return load_from_text_file(stream,stack,buffer_size);
- }
- template <typename T,
- typename Container,
- typename Comparator>
- inline std::size_t load_from_text_file(const std::string& file_name,
- std::priority_queue<T,Container,Comparator>& priority_queue,
- const std::size_t& buffer_size = one_kilobyte)
- {
- std::ifstream stream(file_name.c_str());
- if (!stream)
- return 0;
- else
- return load_from_text_file(stream,priority_queue,buffer_size);
- }
- template <typename T,
- typename Allocator,
- template <typename,typename> class Sequence>
- inline std::size_t write_to_text_file(std::ostream& stream,
- const Sequence<T,Allocator>& sequence,
- const std::string& delimiter = "")
- {
- if (!stream) return 0;
- std::size_t count = 0;
- typename Sequence<T,Allocator>::const_iterator itr = sequence.begin();
- typename Sequence<T,Allocator>::const_iterator end = sequence.end();
- if (!delimiter.empty())
- {
- while (end != itr)
- {
- stream << (*itr) << delimiter;
- ++itr;
- ++count;
- }
- }
- else
- {
- while (end != itr)
- {
- stream << (*itr);
- ++itr;
- ++count;
- }
- }
- return count;
- }
- template <typename T,
- typename Comparator,
- typename Allocator>
- inline std::size_t write_to_text_file(std::ostream& stream,
- const std::set<T,Comparator,Allocator>& set,
- const std::string& delimiter = "")
- {
- if (!stream) return 0;
- std::size_t count = 0;
- typename std::set<T,Comparator,Allocator>::const_iterator itr = set.begin();
- typename std::set<T,Comparator,Allocator>::const_iterator end = set.end();
- if (!delimiter.empty())
- {
- while (end != itr)
- {
- stream << (*itr) << delimiter;
- ++itr;
- ++count;
- }
- }
- else
- {
- while (end != itr)
- {
- stream << (*itr);
- ++itr;
- ++count;
- }
- }
- return count;
- }
- template <typename T,
- typename Comparator,
- typename Allocator>
- inline std::size_t write_to_text_file(std::ostream& stream,
- const std::multiset<T,Comparator,Allocator>& multiset,
- const std::string& delimiter = "")
- {
- if (!stream) return 0;
- std::size_t count = 0;
- typename std::multiset<T,Comparator,Allocator>::const_iterator itr = multiset.begin();
- typename std::multiset<T,Comparator,Allocator>::const_iterator end = multiset.end();
- if (!delimiter.empty())
- {
- while (end != itr)
- {
- stream << (*itr) << delimiter;
- ++itr;
- ++count;
- }
- }
- else
- {
- while (end != itr)
- {
- stream << (*itr);
- ++itr;
- ++count;
- }
- }
- return count;
- }
- template <typename T,
- typename Allocator,
- template <typename,typename> class Sequence>
- inline std::size_t write_to_text_file(const std::string& file_name,
- const Sequence<T,Allocator>& sequence,
- const std::string& delimiter = "")
- {
- std::ofstream stream(file_name.c_str());
- if (!stream)
- return 0;
- else
- return write_to_text_file(stream,sequence,delimiter);
- }
- template <typename T,
- typename Comparator,
- typename Allocator>
- inline std::size_t write_to_text_file(const std::string& file_name,
- const std::set<T,Comparator,Allocator>& set,
- const std::string& delimiter = "")
- {
- std::ofstream stream(file_name.c_str());
- if (!stream)
- return 0;
- else
- return write_to_text_file(stream,set,delimiter);
- }
- template <typename T,
- typename Comparator,
- typename Allocator>
- inline std::size_t write_to_text_file(const std::string& file_name,
- const std::multiset<T,Comparator,Allocator>& multiset,
- const std::string& delimiter = "")
- {
- std::ofstream stream(file_name.c_str());
- if (!stream)
- return 0;
- else
- return write_to_text_file(stream,multiset,delimiter);
- }
- template <typename InputIterator, typename OutputIterator>
- inline void copy_n(InputIterator itr, std::size_t n, OutputIterator out)
- {
- while (n)
- {
- (*out) = (*itr);
- ++itr;
- ++out;
- --n;
- }
- }
- template <typename Predicate,
- typename InputIterator,
- typename OutputIterator>
- inline void copy_if(Predicate predicate,
- const InputIterator begin, const InputIterator end,
- OutputIterator out)
- {
- InputIterator itr = begin;
- while (end != itr)
- {
- if (predicate(*itr))
- {
- *(out++) = (*itr);
- }
- ++itr;
- }
- }
- template <typename Predicate,
- typename InputIterator,
- typename OutputIterator>
- inline InputIterator copy_while(Predicate predicate,
- const InputIterator begin, const InputIterator end,
- OutputIterator out)
- {
- InputIterator itr = begin;
- while (end != itr)
- {
- if (!predicate(*itr))
- return itr;
- *(out++) = *(itr++);
- }
- return end;
- }
- template <typename Predicate,
- typename InputIterator,
- typename OutputIterator>
- inline InputIterator copy_until(Predicate predicate,
- const InputIterator begin, const InputIterator end,
- OutputIterator out)
- {
- InputIterator itr = begin;
- while (end != itr)
- {
- if (predicate(*itr))
- return itr;
- *(out++) = *(itr++);
- }
- return end;
- }
- template <typename InputIterator, typename OutputIterator>
- inline void extract_unique(const InputIterator begin, const InputIterator end,
- OutputIterator out)
- {
- typedef typename std::iterator_traits<InputIterator>::value_type T;
- std::vector<T> buffer(begin,end);
- std::sort(buffer.begin(),buffer.end());
- std::unique_copy(buffer.begin(),buffer.end(),out);
- }
- template <typename Predicate, typename InputIterator>
- inline bool range_only_contains(Predicate predicate,
- const InputIterator begin,
- const InputIterator end)
- {
- InputIterator itr = begin;
- while (end != itr)
- {
- if (!predicate(*itr))
- {
- return false;
- }
- ++itr;
- }
- return true;
- }
- namespace range
- {
- template <typename T>
- class adapter
- {
- public:
- typedef T value_type;
- typedef T* iterator;
- typedef const iterator const_iterator;
- adapter(T* const begin, T* const end)
- : begin_(begin),
- end_(end)
- {}
- adapter(const std::pair<T*,T*>& r)
- : begin_(r.first),
- end_(r.second)
- {}
- adapter(T* const begin, const std::size_t length)
- : begin_(begin),
- end_(begin_ + length)
- {}
- inline iterator begin() const
- {
- return begin_;
- }
- inline iterator end() const
- {
- return end_;
- }
- inline std::size_t size() const
- {
- return std::distance(begin_,end_);
- }
- inline operator std::string() const
- {
- return stringify(begin_,end_);
- }
- inline const T& operator[](const std::size_t& index) const
- {
- return *(begin_ + index);
- }
- inline T& operator[](const std::size_t& index)
- {
- return *(begin_ + index);
- }
- private:
- template <typename Type>
- static inline std::string stringify(Type*,Type*)
- {
- static std::string result = "";
- return result;
- }
- static inline std::string stringify(const char* begin, const char* end)
- {
- return std::string(begin,end);
- }
- iterator begin_;
- iterator end_;
- };
- typedef adapter<const char> string;
- typedef adapter<const unsigned char> ustring;
- template <typename T>
- inline adapter<T> type(const T* begin, const T* end)
- {
- return adapter<T>(begin,end);
- }
- template <typename T, std::size_t N>
- inline adapter<T> type(const T (&t)[N])
- {
- return adapter<T>(t,N);
- }
- static inline adapter<const char> type(const std::string& s)
- {
- return adapter<const char>(s.data(),s.size());
- }
- template <typename T,
- typename Allocator,
- template <typename,typename> class Sequence>
- inline adapter<typename Sequence<T,Allocator>::iterator> type(const Sequence<T,Allocator>& seq)
- {
- return adapter<typename Sequence<T,Allocator>::iterator>(seq.begin(),seq.end());
- }
- inline std::string as_string(const adapter<const char>& a)
- {
- return std::string(a.begin(),a.end());
- }
- inline std::string as_string(const adapter<const unsigned char>& a)
- {
- return std::string(a.begin(),a.end());
- }
- } // namespace range
- template <typename T>
- struct single_delimiter_predicate
- {
- public:
- typedef T value_type;
- single_delimiter_predicate(const T& d)
- : delimiter_(d)
- {}
- inline bool operator()(const T& d) const
- {
- return delimiter_ == d;
- }
- private:
- single_delimiter_predicate<T>& operator=(const single_delimiter_predicate<T>&);
- const T delimiter_;
- };
- template <typename T>
- struct multiple_delimiter_predicate
- {
- public:
- typedef T value_type;
- multiple_delimiter_predicate(const T* d_begin, const T* d_end)
- : length_(std::distance(d_begin,d_end)),
- delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]),
- delimiter_end_(delimiter_ + length_)
- {
- std::copy(d_begin,d_end, delimiter_);
- }
- multiple_delimiter_predicate(const T d[], const std::size_t& length)
- : length_(length),
- delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]),
- delimiter_end_(delimiter_ + length_)
- {
- std::copy(d,d + length, delimiter_);
- }
- template <typename Iterator>
- multiple_delimiter_predicate(const Iterator begin, const Iterator end)
- : length_(std::distance(begin,end)),
- delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]),
- delimiter_end_(delimiter_ + length_)
- {
- //static_assert(T == std::iterator_traits<Iterator>::value_type);
- std::copy(begin,end, delimiter_);
- }
- template <typename Type>
- multiple_delimiter_predicate(const range::adapter<Type>& r)
- : length_(std::distance(r.begin(),r.end())),
- delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]),
- delimiter_end_(delimiter_ + length_)
- {
- //static_assert(T == std::iterator_traits<Iterator>::value_type);
- std::copy(r.begin(),r.end(), delimiter_);
- }
- ~multiple_delimiter_predicate()
- {
- if (length_ > sbo_buffer_size)
- {
- delete[] delimiter_;
- }
- }
- inline bool operator()(const T& d) const
- {
- return (std::find(delimiter_,delimiter_end_,d) != delimiter_end_);
- }
- private:
- multiple_delimiter_predicate(const multiple_delimiter_predicate<T>& mdp);
- multiple_delimiter_predicate& operator=(const multiple_delimiter_predicate<T>& mdp);
- std::size_t length_;
- T* delimiter_;
- T* delimiter_end_;
- enum { sbo_buffer_size = 32 };
- T sbo_buffer[sbo_buffer_size];
- };
- struct multiple_char_delimiter_predicate
- {
- public:
- template <typename Iterator>
- multiple_char_delimiter_predicate(const Iterator begin, const Iterator end)
- {
- setup_delimiter_table(begin,end);
- }
- multiple_char_delimiter_predicate(const std::string& s)
- {
- setup_delimiter_table(s.data(),s.data() + s.size());
- }
- inline bool operator()(const unsigned char& c) const
- {
- return (delimiter_table_[c]);
- }
- inline bool operator()(const char& c) const
- {
- return operator()(static_cast<unsigned char>(c));
- }
- private:
- static const std::size_t table_size = 256;
- template <typename Iterator>
- inline void setup_delimiter_table(const Iterator begin, const Iterator end)
- {
- std::fill_n(delimiter_table_,table_size,false);
- for (Iterator itr = begin; itr != end; ++itr)
- {
- delimiter_table_[static_cast<unsigned char>(*itr)] = true;
- }
- }
- bool delimiter_table_[table_size];
- };
- namespace details
- {
- template <typename Allocator,
- template <typename,typename> class Sequence>
- struct index_remover_impl
- {
- typedef Sequence<std::size_t,Allocator> sequence_t;
- index_remover_impl(const sequence_t& sequence)
- : itr_(sequence.begin()),
- end_(sequence.end()),
- current_index_(0),
- check_(true)
- {}
- template <typename T>
- inline bool operator()(const T&)
- {
- if (check_)
- {
- if (current_index_++ == *itr_)
- {
- if (end_ == ++itr_)
- {
- check_ = false;
- }
- return true;
- }
- }
- return false;
- }
- typename sequence_t::const_iterator itr_;
- typename sequence_t::const_iterator end_;
- std::size_t current_index_;
- bool check_;
- };
- }
- template <typename Allocator,
- template <typename,typename> class Sequence>
- inline details::index_remover_impl<Allocator,Sequence> index_remover(const Sequence<std::size_t,Allocator>& sequence)
- {
- return details::index_remover_impl<Allocator,Sequence>(sequence);
- }
- template <typename Iterator, typename Predicate>
- inline std::size_t remove_inplace(Predicate predicate,
- Iterator begin,
- Iterator end)
- {
- Iterator itr1 = begin;
- Iterator itr2 = begin;
- std::size_t removal_count = 0;
- while (end != itr1)
- {
- if (predicate(*itr1))
- {
- ++itr1;
- ++removal_count;
- }
- else
- {
- if (itr1 != itr2)
- {
- (*itr2) = (*itr1);
- }
- ++itr1;
- ++itr2;
- }
- }
- return removal_count;
- }
- template <typename T, typename Predicate>
- inline std::size_t remove_inplace(Predicate predicate, const range::adapter<T>& r)
- {
- return remove_inplace(predicate,r.begin(),r.end());
- }
- template <typename Predicate,
- typename T,
- typename Allocator,
- template <typename,typename> class Sequence>
- inline std::size_t remove_inplace(Predicate predicate, Sequence<T,Allocator>& sequence)
- {
- const std::size_t removal_count = remove_inplace(predicate,sequence.begin(),sequence.end());
- sequence.resize(sequence.size() - removal_count);
- return removal_count;
- }
- inline void remove_inplace(const std::string::value_type c, std::string& s)
- {
- const std::size_t removal_count = remove_inplace(single_delimiter_predicate<std::string::value_type>(c),
- const_cast<char*>(s.data()),
- const_cast<char*>(s.data() + s.size()));
- if (removal_count > 0)
- {
- s.resize(s.size() - removal_count);
- }
- }
- template <typename Predicate>
- inline void remove_inplace(Predicate predicate, std::string& s)
- {
- const std::size_t removal_count = remove_inplace(predicate,
- const_cast<char*>(s.data()),
- const_cast<char*>(s.data() + s.size()));
- if (removal_count > 0)
- {
- s.resize(s.size() - removal_count);
- }
- }
- template <typename Iterator, typename Predicate>
- inline std::size_t remove_consecutives_inplace(Predicate predicate,
- Iterator begin,
- Iterator end)
- {
- if (0 == std::distance(begin,end)) return 0;
- Iterator itr1 = begin;
- Iterator itr2 = begin;
- typename std::iterator_traits<Iterator>::value_type prev = *begin;
- std::size_t removal_count = 0;
- ++itr1;
- ++itr2;
- while (end != itr1)
- {
- while ((end != itr1) && (!predicate(*itr1) || !predicate(prev)))
- {
- if (itr1 != itr2)
- {
- (*itr2) = (*itr1);
- }
- prev = (*itr1);
- ++itr1;
- ++itr2;
- }
- while ((end != itr1) && predicate(*itr1))
- {
- ++itr1;
- ++removal_count;
- }
- }
- return removal_count;
- }
- template <typename T, typename Predicate>
- inline std::size_t remove_consecutives_inplace(Predicate predicate, const range::adapter<T>& r)
- {
- return remove_consecutives_inplace(predicate,r.begin(),r.end());
- }
- inline void remove_consecutives_inplace(const std::string::value_type c, std::string& s)
- {
- if (s.empty()) return;
- const std::size_t removal_count = remove_consecutives_inplace(single_delimiter_predicate<std::string::value_type>(c),
- const_cast<char*>(s.data()),
- const_cast<char*>(s.data() + s.size()));
- if (removal_count > 0)
- {
- s.resize(s.size() - removal_count);
- }
- }
- inline void remove_consecutives_inplace(const std::string& rem_chars, std::string& s)
- {
- if (s.empty()) return;
- const std::size_t removal_count = remove_consecutives_inplace(multiple_char_delimiter_predicate(rem_chars),
- const_cast<char*>(s.data()),
- const_cast<char*>(s.data() + s.size()));
- if (removal_count > 0)
- {
- s.resize(s.size() - removal_count);
- }
- }
- namespace details
- {
- #if (defined(__MINGW32_VERSION)) ||\
- (defined(__APPLE__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070)) ||\
- (defined(_WIN32) && (_MSC_VER < 1400))
- inline std::size_t strnlength(const char* s, const std::size_t& n)
- {
- const char *end = reinterpret_cast<const char*>(memchr(s, '\0', n));
- return end ? (size_t) (end - s) : n;
- }
- #else
- inline std::size_t strnlength(const char* s, const std::size_t& n)
- {
- return strnlen(s,n);
- }
- #endif
- }
- inline void remove_consecutives_inplace(const char* rem_chars, std::string& s)
- {
- if (s.empty()) return;
- const std::size_t removal_count = remove_consecutives_inplace(multiple_char_delimiter_predicate(
- rem_chars,
- rem_chars + details::strnlength(rem_chars,256)),
- const_cast<char*>(s.data()),
- const_cast<char*>(s.data() + s.size()));
- if (removal_count > 0)
- {
- s.resize(s.size() - removal_count);
- }
- }
- template <typename Predicate>
- inline void remove_consecutives_inplace(Predicate predicate, std::string& s)
- {
- if (s.empty()) return;
- const std::size_t removal_count = remove_consecutives_inplace(predicate,
- const_cast<char*>(s.data()),
- const_cast<char*>(s.data() + s.size()));
- if (removal_count > 0)
- {
- s.resize(s.size() - removal_count);
- }
- }
- template <typename Iterator>
- inline std::size_t remove_consecutives_inplace(Iterator begin, Iterator end)
- {
- if (0 == std::distance(begin,end)) return 0;
- Iterator itr1 = begin; ++itr1;
- Iterator itr2 = begin; ++itr2;
- typename std::iterator_traits<Iterator>::value_type prev = *begin;
- std::size_t removal_count = 0;
- while (end != itr1)
- {
- while ((end != itr1) && (prev != (*itr1)))
- {
- if (itr1 != itr2)
- {
- (*itr2) = (*itr1);
- }
- prev = (*itr1);
- ++itr1;
- ++itr2;
- }
- while ((end != itr1) && (prev == (*itr1)))
- {
- ++itr1;
- ++removal_count;
- }
- }
- return removal_count;
- }
- template <typename T>
- inline std::size_t remove_consecutives_inplace(const range::adapter<T>& r)
- {
- return remove_consecutives_inplace(r.begin(),r.end());
- }
- template <typename T,
- typename Allocator,
- template <typename,typename> class Sequence>
- inline void remove_consecutives_inplace(Sequence<T,Allocator>& sequence)
- {
- const std::size_t removal_count = remove_consecutives_inplace(sequence.begin(),sequence.end());
- sequence.resize(sequence.size() - removal_count);
- }
- inline void remove_consecutives_inplace(std::string& s)
- {
- std::size_t removal_count = remove_consecutives_inplace(const_cast<char*>(s.data()),
- const_cast<char*>(s.data() + s.size()));
- if (removal_count > 0)
- {
- s.resize(s.size() - removal_count);
- }
- }
- inline std::string remove_duplicates(const std::string& str)
- {
- std::string::value_type table[0xFF];
- std::fill_n(table,0xFF,static_cast<char>(0));
- std::string result;
- result.reserve(str.size());
- for (std::size_t i = 0; i < str.size(); ++i)
- {
- const char c = str[i];
- if (0 == table[static_cast<std::size_t>(c)])
- {
- table[static_cast<std::size_t>(c)] = 0x01;
- result += c;
- }
- }
- return result;
- }
- inline std::string remove_duplicates_inplace(std::string& str)
- {
- return remove_duplicates(str);
- }
- template <typename Iterator, typename Predicate>
- inline std::size_t remove_trailing(Predicate predicate,
- Iterator begin,
- Iterator end)
- {
- const std::size_t length = std::distance(begin,end);
- if (0 == length)
- return 0;
- Iterator itr = begin + (length - 1);
- std::size_t removal_count = 0;
- while ((begin != itr) && predicate(*itr))
- {
- --itr;
- ++removal_count;
- }
- return removal_count;
- }
- template <typename T, typename Predicate>
- inline std::size_t remove_trailing(Predicate predicate, const range::adapter<T>& r)
- {
- return remove_trailing(predicate,r.begin(),r.end());
- }
- inline void remove_trailing(const std::string::value_type c, std::string& s)
- {
- if (s.empty()) return;
- const std::size_t removal_count = remove_trailing(single_delimiter_predicate<std::string::value_type>(c),
- const_cast<char*>(s.data()),
- const_cast<char*>(s.data() + s.size()));
- if (removal_count > 0)
- {
- s.resize(s.size() - removal_count);
- }
- }
- inline void remove_trailing(const std::string& rem_chars, std::string& s)
- {
- if (s.empty()) return;
- const std::size_t removal_count = remove_trailing(multiple_char_delimiter_predicate(rem_chars),
- const_cast<char*>(s.data()),
- const_cast<char*>(s.data() + s.size()));
- if (removal_count > 0)
- {
- s.resize(s.size() - removal_count);
- }
- }
- inline void remove_trailing(const char* rem_chars, std::string& s)
- {
- const std::size_t removal_count = remove_trailing(multiple_char_delimiter_predicate(
- rem_chars,
- rem_chars + details::strnlength(rem_chars,256)),
- const_cast<char*>(s.data()),
- const_cast<char*>(s.data() + s.size()));
- if (removal_count > 0)
- {
- s.resize(s.size() - removal_count);
- }
- }
- template <typename Predicate>
- inline void remove_trailing(Predicate predicate, std::string& s)
- {
- if (s.empty()) return;
- const std::size_t removal_count = remove_trailing(predicate,
- const_cast<char*>(s.data()),
- const_cast<char*>(s.data() + s.size()));
- if (removal_count > 0)
- {
- s.resize(s.size() - removal_count);
- }
- }
- template <typename Iterator, typename Predicate>
- inline std::size_t remove_leading(Predicate predicate,
- Iterator begin,
- Iterator end)
- {
- const std::size_t length = std::distance(begin,end);
- if (0 == length)
- return 0;
- Iterator itr = begin;
- std::size_t removal_count = 0;
- while ((end != itr) && predicate(*itr))
- {
- ++itr;
- ++removal_count;
- }
- std::copy(itr,end,begin);
- return removal_count;
- }
- template <typename T, typename Predicate>
- inline std::size_t remove_leading(Predicate predicate, const range::adapter<T>& r)
- {
- return remove_leading(predicate,r.begin(),r.end());
- }
- inline void remove_leading(const std::string::value_type c, std::string& s)
- {
- if (s.empty()) return;
- const std::size_t removal_count = remove_leading(single_delimiter_predicate<std::string::value_type>(c),
- const_cast<char*>(s.data()),
- const_cast<char*>(s.data() + s.size()));
- if (removal_count > 0)
- {
- s.resize(s.size() - removal_count);
- }
- }
- inline void remove_leading(const std::string& rem_chars, std::string& s)
- {
- if (s.empty()) return;
- const std::size_t removal_count = remove_leading(multiple_char_delimiter_predicate(rem_chars),
- const_cast<char*>(s.data()),
- const_cast<char*>(s.data() + s.size()));
- if (removal_count > 0)
- {
- s.resize(s.size() - removal_count);
- }
- }
- inline void remove_leading(const char* rem_chars, std::string& s)
- {
- if (s.empty()) return;
- const std::size_t removal_count = remove_leading(multiple_char_delimiter_predicate(
- rem_chars,
- rem_chars + details::strnlength(rem_chars,256)),
- const_cast<char*>(s.data()),
- const_cast<char*>(s.data() + s.size()));
- if (removal_count > 0)
- {
- s.resize(s.size() - removal_count);
- }
- }
- inline void remove_leading_trailing(const std::string& rem_chars, std::string& s)
- {
- remove_leading(rem_chars,s);
- remove_trailing(rem_chars,s);
- }
- template <typename Predicate>
- inline void remove_leading(Predicate predicate, std::string& s)
- {
- if (s.empty()) return;
- const std::size_t removal_count = remove_leading(predicate,
- const_cast<char*>(s.data()),
- const_cast<char*>(s.data() + s.size()));
- if (removal_count > 0)
- {
- s.resize(s.size() - removal_count);
- }
- }
- template <typename Allocator,
- template <typename,typename> class Sequence>
- void remove_empty_strings(Sequence<std::string,Allocator>& seq)
- {
- struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } };
- seq.erase(std::remove_if(seq.begin(),seq.end(),is_empty::check),seq.end());
- }
- template <typename Allocator>
- void remove_empty_strings(std::list<std::string,Allocator>& l)
- {
- struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } };
- l.remove_if(is_empty::check);
- }
- template <typename Comparator, typename Allocator>
- void remove_empty_strings(std::set<std::string,Comparator,Allocator>& set)
- {
- struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } };
- typename std::set<std::string,Comparator,Allocator>::iterator itr = set.begin();
- while (set.end() != itr)
- {
- if ((*itr).empty())
- set.erase(itr++);
- else
- ++itr;
- }
- }
- template <typename Comparator, typename Allocator>
- void remove_empty_strings(std::multiset<std::string,Comparator,Allocator>& set)
- {
- struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } };
- typename std::multiset<std::string,Comparator,Allocator>::iterator itr = set.begin();
- while (set.end() != itr)
- {
- if ((*itr).empty())
- set.erase(itr++);
- else
- ++itr;
- }
- }
- template <typename Iterator>
- inline void replace(const typename std::iterator_traits<Iterator>::value_type& c1,
- const typename std::iterator_traits<Iterator>::value_type& c2,
- const Iterator begin,
- …
Large files files are truncated, but you can click here to view the full file