This is an automated email from the git hooks/post-receive script. plessy pushed a commit to branch debian/unstable in repository libgtextutils.
commit edb807fc6001f3a3d07e07a16ed5f8363521d56a Author: A. Gordon <[email protected]> Date: Tue Mar 24 16:44:48 2009 -0400 Cleaned 'container_join', added usage examples. --- src/gtextutils/container_join.h | 201 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) diff --git a/src/gtextutils/container_join.h b/src/gtextutils/container_join.h new file mode 100755 index 0000000..7c6a7c4 --- /dev/null +++ b/src/gtextutils/container_join.h @@ -0,0 +1,201 @@ +/* + Gordon's Text-Utilities Library + Copyright (C) 2009 Assaf Gordon ([email protected]) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/> +*/ +#ifndef __LIBGTEXTUTILS_CONTAINER_JOIN_H__ +#define __LIBGTEXTUTILS_CONTAINER_JOIN_H__ + +/* + * Easily joins a container and outputs it to a stream. + * + * Tries to emulate Perl's join in an STL way. + +Usage: + + send container's elements into an output-stream: + + STD::OSTREAM << join ( CONTAINER, [DELIMITER] ) ; + STD::OSTREAM << join ( BEGIN-ITERATOR, END-ITERATOR, [DELIMITER] ) ; + + send container's elements into a string: + + STD::STRING = join ( CONTAINER, [DELIMITER] ) ; + STD::STRING = join ( BEGIN-ITERATOR, END-ITERATOR, [DELIMITER] ) ; + + [DELIMITER] = optional std::string, will be used as delimiter between two elements. + defaults to a single tab. + can contain multiple characters. + +Usage example: + + // A simple container (could also be a list/deque/stack/whatever): + vector<int> v; + for (int i=0;i<10;++i) + v.push_back(i); + + // Print the entire container: + cout << join(v,",") << endl; + // Will output: 0,1,2,3,4,5,6,7,8,9 + + // Print specific range, using begin/end iterators + cout << join(v.begin(), v.end(),"-") << endl; + // Will output: 0-1-2-3-4-5-6-7-8-9 + + // An std::pair<> based container + // map/set/multimap/multiset/unorederd_map etc. + // or + // vector< pair<A,B> > etc. + map<int, string> m; + m[42] = "Don't Panic"; + m[666]= "Beast" ; + + // Print the first values (of the pair) of the entire container: + cout << "keys = " << join_firsts(m) << endl; + // Will output: 42 <tab> 666 + + // Print the first values (of the pair) of a specific range: + cout << "keys = " << join_firsts(m.begin(), m.end(), ",") << endl; + // Will output: 42,666 + + // Print the second values (of the pair) of the entire container: + cout << "values= " << join_seconds(m) << endl; + // Will output: Don't Panic<tab>Beast + + // Print the second values (of the pair) of a specific range: + cout << "values= " << join_seconds(m.begin(), m.end(), ",") << endl; + // Will output: Don't Panic,Beast + + + // Store result in a string (instead of an output stream): + string s = join_firsts(m); + // 's' will contain: "42\t666"; + + +*/ + + +#include <ostream> +#include <sstream> +#include <iostream> +#include <iterator> +#include <algorithm> + +template<typename ITERATOR, typename OP> +struct joiner +{ + joiner ( ITERATOR _begin, ITERATOR _end, const std::string& _delimiter="\t" ) : + begin(_begin), + end(_end), + delimiter(_delimiter) + {} + + ITERATOR begin, end; + std::string delimiter; + OP op; + + operator std::string() const + { + std::ostringstream os; + os << *this; + return os.str(); + } +}; + +template<typename ITERATOR, typename OP> +inline std::ostream& operator<< ( std::ostream& strm, const joiner<ITERATOR, OP>& j ) +{ + ITERATOR it = j.begin; + if (it != j.end) { + //first element - doesn't need a delimiter + strm << j.op(*it); + it++; + } + for (; it != j.end ; ++it) { + //print a delimiter before all other elements + strm << j.delimiter ; + strm << j.op(*it); + } + return strm; +} + +template <typename T> +struct joiner_noop +{ +const T& operator() (const T& t) const { return t; } +}; + +template <typename FIRST, typename SECOND> +struct joiner_select1st +{ +const FIRST& operator() ( const std::pair<FIRST,SECOND>& pair ) const { return pair.first ; } +}; + +template <typename FIRST, typename SECOND> +struct joiner_select2nd +{ +const SECOND& operator() ( const std::pair<FIRST,SECOND>& pair ) const { return pair.second; } +}; + +template<typename ITERATOR > +inline +joiner< ITERATOR, joiner_noop<typename ITERATOR::value_type> > +join(ITERATOR begin, ITERATOR end, const std::string& delimiter="\t") +{ + return joiner< ITERATOR, joiner_noop<typename ITERATOR::value_type> > (begin, end, delimiter); +} + +template<typename ITERATOR > +inline +joiner< ITERATOR, joiner_select1st<typename ITERATOR::value_type::first_type, typename ITERATOR::value_type::second_type> > +join_firsts(ITERATOR begin, ITERATOR end, const std::string& delimiter="\t") +{ + return joiner< ITERATOR, joiner_select1st<typename ITERATOR::value_type::first_type, typename ITERATOR::value_type::second_type> > (begin, end, delimiter); +} + +template<typename ITERATOR > +inline +joiner< ITERATOR, joiner_select2nd<typename ITERATOR::value_type::first_type, typename ITERATOR::value_type::second_type> > +join_seconds(ITERATOR begin, ITERATOR end, const std::string& delimiter="\t") +{ + return joiner< ITERATOR, joiner_select2nd<typename ITERATOR::value_type::first_type, typename ITERATOR::value_type::second_type> > (begin, end, delimiter); +} + +template<typename CONTAINER> +inline +joiner< typename CONTAINER::const_iterator, joiner_noop<typename CONTAINER::value_type> > +join(const CONTAINER& a, const std::string& delimiter="\t") +{ + return join(a.begin(), a.end(), delimiter); +} + + +template<typename CONTAINER> +inline +joiner< typename CONTAINER::const_iterator, joiner_select1st<typename CONTAINER::value_type::first_type, typename CONTAINER::value_type::second_type> > +join_firsts(const CONTAINER& a, const std::string& delimiter="\t") +{ + return join_firsts(a.begin(), a.end(), delimiter); +} + +template<typename CONTAINER> +inline +joiner< typename CONTAINER::const_iterator, joiner_select2nd<typename CONTAINER::value_type::first_type, typename CONTAINER::value_type::second_type> > +join_seconds(const CONTAINER& a, const std::string& delimiter="\t") +{ + return join_seconds(a.begin(), a.end(), delimiter); +} + +#endif -- Alioth's /git/debian-med/git-commit-notice on /srv/git.debian.org/git/debian-med/libgtextutils.git _______________________________________________ debian-med-commit mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/debian-med-commit
