00001 ////////////////////////////////////////////////////////////////////////////////////////////////// 00002 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. 00003 // Produced at the Lawrence Livermore National Laboratory 00004 // LLNL-CODE-433662 00005 // All rights reserved. 00006 // 00007 // This file is part of Muster. For details, see http://github.com/tgamblin/muster. 00008 // Please also read the LICENSE file for further information. 00009 // 00010 // Redistribution and use in source and binary forms, with or without modification, are 00011 // permitted provided that the following conditions are met: 00012 // 00013 // * Redistributions of source code must retain the above copyright notice, this list of 00014 // conditions and the disclaimer below. 00015 // * Redistributions in binary form must reproduce the above copyright notice, this list of 00016 // conditions and the disclaimer (as noted below) in the documentation and/or other materials 00017 // provided with the distribution. 00018 // * Neither the name of the LLNS/LLNL nor the names of its contributors may be used to endorse 00019 // or promote products derived from this software without specific prior written permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 00022 // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00023 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 00024 // LAWRENCE LIVERMORE NATIONAL SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE 00025 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00026 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00027 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00028 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00029 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 ////////////////////////////////////////////////////////////////////////////////////////////////// 00031 00032 /// 00033 /// @file counter.h 00034 /// @author Todd Gamblin tgamblin@llnl.gov 00035 /// @brief Dummy output iterator that counts how many times it was assigned to. 00036 /// without actually storing anything. 00037 /// 00038 #ifndef COUNTER_ITERATOR_H 00039 #define COUNTER_ITERATOR_H 00040 00041 #include <cstdlib> 00042 #include <iterator> 00043 00044 namespace cluster { 00045 00046 /// 00047 /// Counting output iterator that records how many times an output iterator 00048 /// was assigned to, but ignores the value stored. 00049 /// 00050 /// This is useful if you just want to know the size of something that an STL 00051 /// algorithm would output, without actually allocating space for it. 00052 /// 00053 /// @note 00054 /// Don't use this directly; Instantiate this using the counter() template function 00055 /// so that you don't have to supply a type (see sample usage in file docs). 00056 /// 00057 template <class T> 00058 struct counter_iterator { 00059 typedef T value_type; 00060 typedef T* pointer; 00061 typedef T& reference; 00062 typedef size_t difference_type; 00063 typedef std::output_iterator_tag iterator_category; 00064 00065 /// struct representation of a no-op. Makes assignment to target do nothing. 00066 struct target { 00067 void operator=(T t) { } 00068 }; 00069 00070 pointer count; 00071 counter_iterator(value_type& c) : count(&c) { *count = 0; } 00072 counter_iterator(const counter_iterator& other) : count(other.count) { } 00073 counter_iterator& operator=(const counter_iterator& other) { count = other.count; return *this; } 00074 target operator*() { return target(); } 00075 counter_iterator& operator++() { (*count)++; return *this; } 00076 counter_iterator operator++(int) { (*count)++; return *this; } 00077 }; 00078 00079 /// 00080 /// Adaptor for creating type-inferred counters. 00081 /// 00082 /// <b>Example Usage:</b> 00083 /// @code 00084 /// #include <algorithm> 00085 /// 00086 /// // construct two sets 00087 /// set<int> s1, s2; 00088 /// 00089 /// // insert some things so that their intersection has 2 ints. 00090 /// s1.insert(1); s1.insert(2); s1.insert(3); 00091 /// s2.insert(2); s2.insert(3); s2.insert(4); 00092 /// 00093 /// // Compute intersection, but throw away the values and just 00094 /// // store the size in the count variable. 00095 /// size_t count; 00096 /// set_intersection(s1.begin(), s1.end(), 00097 /// s2.begin(), s2.end(), counter(count)); 00098 /// 00099 /// // now count == 2, since 2 items were inserted 00100 /// // by <code>set_intersection. 00101 /// 00102 /// @endcode 00103 /// 00104 template <class T> 00105 counter_iterator<T> counter(T& ref) { 00106 return counter_iterator<T>(ref); 00107 } 00108 00109 } // namespace cluster 00110 00111 #endif // COUNTER_ITERATOR_H