diff --git a/examples/applications/CMakeLists.txt b/examples/applications/CMakeLists.txt index 2bd9f2d59..f178cf2bd 100644 --- a/examples/applications/CMakeLists.txt +++ b/examples/applications/CMakeLists.txt @@ -13,6 +13,7 @@ if(NOT CYGWIN AND NOT MINGW) #-tb too big to build on cygwin stxxl_build_example(skew3) + stxxl_build_example(skew3-lcp) if(MSVC AND BUILD_TESTS) # requires /bigobj flag to build @@ -20,5 +21,6 @@ if(NOT CYGWIN AND NOT MINGW) #-tb too big to build on cygwin endif() stxxl_test(skew3 --size 1mib random --check) + stxxl_test(skew3-lcp --size 1mib random --check) endif() \ No newline at end of file diff --git a/examples/applications/skew3-lcp.cpp b/examples/applications/skew3-lcp.cpp new file mode 100644 index 000000000..74a11bede --- /dev/null +++ b/examples/applications/skew3-lcp.cpp @@ -0,0 +1,2909 @@ +/*************************************************************************** + * examples/applications/skew3-lcp.cpp + * + * Implementation of the DC3-LCP aka skew3-lcp algorithm in external memory, + * based on the internal memory version described in Juha Kaerkkaeinen, + * Peter Sanders and Stefan Burkhardt. "Linear work suffix array construction". + * Journal of the ACM, Volume 53 Issue 6, November 2006, Pages 918-936. + * + * Part of the STXXL. See http://stxxl.sourceforge.net + * + * Copyright (C) 2004 Jens Mehnert + * Copyright (C) 2012-2015 Timo Bingmann + * Copyright (C) 2012-2015 Daniel Feist + * + * 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) + **************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using stxxl::internal_size_type; +using stxxl::external_size_type; + +/// Global variables, types and helpers. + +// limits max ram used by external data structures to 1.0 GiB the conservative +// way +internal_size_type ram_use = 0.8 * 1024 * 1024 * 1024; + +// alphabet data type +typedef unsigned char alphabet_type; + +// calculation data type +typedef external_size_type size_type; + +/// Suffix array checker for correctness verification. + +/** + * Algorithm to check whether the suffix array is correct. Loosely based on the + * ideas of Kaerkkaeinen und Burghardt, originally implemented in STXXL by Jens + * Mehnert (2004), reimplemented using triples by Timo Bingmann (2012). + * + * \param InputT is the original text, from which the suffix array was build. + * \param InputSA is the suffix array from InputT. + * \return true iff InputSA is the correct suffix array of InputT, else false. + * + * Note: ISA := The inverse of SA. + */ +template +bool sacheck(InputT& inputT, InputSA& inputSA) +{ + typedef typename InputSA::value_type offset_type; + typedef stxxl::tuple pair_type; + typedef stxxl::tuple triple_type; + + /// Pipeline Declaration + + // build tuples with index: (SA[i]) -> (i, SA[i]) + typedef stxxl::stream::counter index_counter_type; + index_counter_type index_counter; + + typedef stxxl::stream::make_tuple tuple_index_sa_type; + tuple_index_sa_type tuple_index_sa(index_counter, inputSA); + + // take (i, SA[i]) and sort to (ISA[i], i) + typedef stxxl::tuple_less2nd pair_less_type; + typedef typename stxxl::stream::sort build_isa_type; + + build_isa_type build_isa(tuple_index_sa, pair_less_type(), ram_use / 3); + + // build (ISA[i], T[i], ISA[i+1]) and sort to (i, T[SA[i]], ISA[SA[i]+1]) + typedef stxxl::tuple_less1st triple_less_type; // comparison relation + + typedef typename stxxl::stream::use_push triple_push_type; // indicator use push() + typedef typename stxxl::stream::runs_creator triple_rc_type; + typedef typename stxxl::stream::runs_merger triple_rm_type; + + triple_rc_type triple_rc(triple_less_type(), ram_use / 3); + + /// Process + + // loop 1: read ISA and check for a permutation. + // simultaneously create runs of triples by iterating ISA and T. + size_type totalSize; + { + offset_type prev_isa = (*build_isa).first; + offset_type counter = 0; + while (!build_isa.empty()) { + if ((*build_isa).second != counter) { + std::cout << "Error: suffix array is not a permutation of 0..n-1." << std::endl; + return false; + } + + ++counter; + ++build_isa; // ISA is one in front of T + + if (!build_isa.empty()) { + triple_rc.push(triple_type(prev_isa, *inputT, (*build_isa).first)); + prev_isa = (*build_isa).first; + } + ++inputT; + } + + totalSize = counter; + } + + if (totalSize == 1) return true; + + // loop 2: read triples (i,T[SA[i]],ISA[SA[i]+1]) and check for correct ordering. + triple_rm_type triple_rm(triple_rc.result(), triple_less_type(), ram_use / 3); + + { + triple_type prev_triple = *triple_rm; + size_type counter = 0; + + ++triple_rm; + + while (!triple_rm.empty()) { + const triple_type& this_triple = *triple_rm; + + if (prev_triple.second > this_triple.second) + { + // simple check of first character of suffix + std::cout << "Error: suffix array position " + << counter << " ordered incorrectly." << std::endl; + return false; + } + else if (prev_triple.second == this_triple.second) { + if (this_triple.third == (offset_type)totalSize) { + // last suffix of string must be first among those with same first character + std::cout << "Error: suffix array position " + << counter << " ordered incorrectly." << std::endl; + return false; + } + if (prev_triple.third != (offset_type)totalSize && + prev_triple.third > this_triple.third) { + // positions SA[i] and SA[i-1] has same first character but their suffixes are ordered incorrectly: + // the suffix position of SA[i] is given by ISA[SA[i]] + std::cout << "Error: suffix array position " + << counter << " ordered incorrectly." << std::endl; + return false; + } + } + + prev_triple = this_triple; + + ++triple_rm; + ++counter; + } + } + return true; +} + +/// Wrapper for suffix array checker class sachecker. + +/** + * Wrapper function for sachecker. + * + * \param InputT is the original text, from which the suffix array was built. + * \param InputSA is the suffix array from InputT. + * \return true iff InputSA is the correct suffix array of InputT, else false. + */ +template +bool sacheck_vectors(InputT& inputT, InputSA& inputSA) +{ + typename stxxl::stream::streamify_traits::stream_type streamT + = stxxl::stream::streamify(inputT.begin(), inputT.end()); + + typename stxxl::stream::streamify_traits::stream_type streamSA + = stxxl::stream::streamify(inputSA.begin(), inputSA.end()); + + return sacheck(streamT, streamSA); +} + +/// Kasai's semi external lcp array calculator. + +template +struct sa_index_stream_type +{ + typedef typename InputStream::value_type offset_type; + typedef stxxl::tuple value_type; + +private: + size_type m_counter; + + InputStream& m_input; + + value_type m_curr; + +public: + sa_index_stream_type(InputStream& input) : m_counter(0), m_input(input) + { + if (!m_input.empty()) + m_curr = value_type(*m_input, m_counter++, 0); + } + + const value_type& operator * () const + { + return m_curr; + } + + sa_index_stream_type& operator ++ () + { + ++m_input; + if (!m_input.empty()) + m_curr = value_type(*m_input, m_counter++, m_curr.first); + return *this; + } + + bool empty() const + { + return m_input.empty(); + } +}; + +/** + * Algorithm to calculate the LCP array from a string and suffix array in linear + * time. Based on the ideas of Kasai et al. (2001), implemented by Timo + * Bingmann (2012). + * + * \param &string is a reference to the input sequence container. + * \param &SA is a reference to the suffix array container. + * \param &lcp is a reference to the container which stores the lcp array + * calculated by the algorithm. + */ +template +void lcparray_stxxl_kasai(const StringContainer& string, + const SAContainer& SA, LCPContainer& lcp) +{ + assert(string.size() == SA.size()); + + /// Generate ISA. + + typedef typename StringContainer::value_type alphabet_type; + typedef typename SAContainer::value_type offset_type; + typedef typename SAContainer::size_type size_type; + + static const std::size_t block_size = sizeof(offset_type) * 1024 * 1024 / 2; + + typedef stxxl::tuple offset_pair_type; + typedef stxxl::tuple offset_triple_type; + + // define stream iterating over a STXXL vector + typedef stxxl::stream::iterator2stream sa_stream_type; + sa_stream_type sa_stream(SA.begin(), SA.end()); + sa_index_stream_type sa_index_stream(sa_stream); + + // comparator for ISA sort: 1st component ascending + typedef stxxl::tuple_less1st offset_triple_less1st_type; + offset_triple_less1st_type offset_triple_less1st; + + // runs creator for ISA stream + typedef stxxl::stream::sort, offset_triple_less1st_type, block_size> isa_sort_type; + isa_sort_type isa_sort(sa_index_stream, offset_triple_less1st, ram_use / 8, ram_use / 8); + + /// Output sorter. + + typedef stxxl::tuple_less1st_less2nd offset_pair_less1st_type; + offset_pair_less1st_type offset_pair_less1st; + + typedef stxxl::sorter lcp_sorter_type; + lcp_sorter_type lcp_sorter(offset_pair_less1st, ram_use / 8); + + /// Kasai algorithm: iterate over ISA. + + { + size_type h = 0; // current height + size_type i = 0; // ISA index counter; + + lcp_sorter.push(offset_pair_type(0, 0)); + + std::vector stringRAM(string.begin(), string.end()); + + while (!isa_sort.empty()) { + offset_type k = isa_sort->second; // k = ISA[i] + + if (k > offset_type(0)) { + size_type j = isa_sort->third; // j = SA[k-1]; + + while (i + h < stringRAM.size() && j + h < stringRAM.size() && + stringRAM[i + h] == stringRAM[j + h]) + h++; + + lcp_sorter.push(offset_pair_type(k, h)); + } + if (h > 0) h--; + + ++isa_sort, ++i; + } + } + + /// Collect output. + + stxxl::stream::choose pair_2nd_stream(lcp_sorter); + + lcp.resize(string.size()); + lcp_sorter.sort(); + + stxxl::stream::materialize(pair_2nd_stream, lcp.begin(), lcp.end()); +} + +namespace algo { + +/* + * Class which implements the DC3-LCP aka skew3-lcp algorithm. + * T := input string. The recursion works as follows: + * Step 1: a) convert T into stream of quadruples (i,T[i],T[i+1],T[i+2],T[i+3]) (-> make_quads class) + * b) pick all mod1/mod2 triples T[i],T[i+1],T[i+2] at position i mod 3 != 0 (-> extract_mod12 class) + * b) sort mod1/mod2 triples lexicographically (-> build_sa class) + * c) give mod1/mod2 triples lexicographical ascending names and + * save overlap of neighbored triples in LCPn (-> naming class) + * d) check lexicographical names for uniqueness (-> naming class) + * If yes: proceed with Step 2, If no: set T' := "lexicographical names" and recurse + (i.e. run Step 1 again) which returns SA12 := SA(T') and LCP12 := LCPn(T') + * Step 2: a) by sorting the lexicographical names n we receive ranks r which represent ISA. + * b) construct mod0-quints, mod1-quads and mod2-quints (-> build_sa class) + * c) prepare for merging by: + * sort mod0-quints by 2 components, sort mod1-quads / mod2-quints by one component (-> build_sa class) + * c) merge {mod0-quints, mod1-quads, mod2-quints} and + * compare first characters of tuples, + * perform an RMQ on LCP12, + * perform an RMQ on LCPn (-> merge_sa_lcp class) + * Step 3: a) return Suffix and LCP array of T + * + * \param offset_type later suffix array data type + */ +template +class skew +{ +public: + /// Types and comparators needed by the skew algorithm. + + struct intPair + { + offset_type id, i, j; + + intPair() { } + + intPair(offset_type _id, offset_type _i, offset_type _j) + : id(_id), i(_i), j(_j) { } + }; + + struct leftRmq + { + offset_type id, i, j, k; + + leftRmq() { } + + leftRmq(offset_type _id, offset_type _i, offset_type _j, offset_type _k) + : id(_id), i(_i), j(_j), k(_k) { } + }; + + struct leftRmqComparator + { + bool operator () (const leftRmq& a, const leftRmq& b) const + { + return a.k < b.k; + } + + leftRmq min_value() const + { + return leftRmq(std::numeric_limits::min(), + std::numeric_limits::min(), + std::numeric_limits::min(), + std::numeric_limits::min()); + } + + leftRmq max_value() const + { + return leftRmq(std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::max()); + } + }; + + struct rightRmq + { + offset_type id, i, j, k, tmpK; + + rightRmq() { } + + rightRmq(offset_type _id, offset_type _i, offset_type _j, offset_type _k, offset_type _tmpK) + : id(_id), i(_i), j(_j), k(_k), tmpK(_tmpK) { } + }; + + struct rightRmqComparator + { + bool operator () (const rightRmq& a, const rightRmq& b) const + { + return a.k < b.k; + } + + rightRmq min_value() const + { + return rightRmq(std::numeric_limits::min(), + std::numeric_limits::min(), + std::numeric_limits::min(), + std::numeric_limits::min(), + std::numeric_limits::min()); + } + + rightRmq max_value() const + { + return rightRmq(std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::max()); + } + }; + + struct finalPair + { + offset_type id, min; + + finalPair() { } + + finalPair(offset_type _id, offset_type _min) + : id(_id), min(_min) { } + }; + + struct finalPairComparator + { + bool operator () (const finalPair& a, const finalPair& b) const + { + return a.id < b.id; + } + + finalPair min_value() const + { + return finalPair(std::numeric_limits::min(), + std::numeric_limits::min()); + } + + finalPair max_value() const + { + return finalPair(std::numeric_limits::max(), + std::numeric_limits::max()); + } + }; + + struct two_tuple + { + offset_type first, second; + + two_tuple() { } + + two_tuple(offset_type _first, offset_type _second) + : first(_first), second(_second) { } + }; + + struct l3Tuple + { + offset_type first; + bool second; + offset_type third, fourth; + + l3Tuple() { } + + l3Tuple(offset_type _first, bool _second, offset_type _third, offset_type _fourth) + : first(_first), second(_second), third(_third), fourth(_fourth) { } + }; + + struct l3TupleComparator + { + bool operator () (const l3Tuple& a, const l3Tuple& b) const + { + return a.third < b.third; + } + + l3Tuple min_value() const + { + return l3Tuple(std::numeric_limits::min(), + std::numeric_limits::min(), + std::numeric_limits::min(), + std::numeric_limits::min()); + } + + l3Tuple max_value() const + { + return l3Tuple(std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::max()); + } + }; + + struct innerTuple + { + offset_type first; + bool second; + offset_type third; + + innerTuple() { } + + innerTuple(offset_type _first, bool _second, offset_type _third) + : first(_first), second(_second), third(_third) { } + }; + + struct innerTupleComparator + { + bool operator () (const innerTuple& x, const innerTuple& y) const + { + return x.third < y.third; + } + + innerTuple min_value() const + { + return innerTuple(std::numeric_limits::min(), + std::numeric_limits::min(), + std::numeric_limits::min()); + } + + innerTuple max_value() const + { + return innerTuple(std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::max()); + } + }; + + struct pos_pair + { + offset_type first; + bool second; + offset_type third; + + pos_pair() { } + + pos_pair(offset_type _first, bool _second, offset_type _third) + : first(_first), second(_second), third(_third) { } + }; + + struct PairComparator + { + bool operator () (const pos_pair& x, const pos_pair& y) const + { + return x.first < y.first; + } + + pos_pair min_value() const + { + return pos_pair(std::numeric_limits::min(), + std::numeric_limits::min(), + std::numeric_limits::min()); + } + + pos_pair max_value() const + { + return pos_pair(std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::max()); + } + }; + + // 2-tuple, 3-tuple, 4-tuple (=quads), 5-tuple(=quints) definition + typedef stxxl::tuple skew_pair_type; + typedef stxxl::tuple skew_triple_type; + typedef stxxl::tuple skew_quad_type; + typedef stxxl::tuple skew_quint_type; + + static const std::size_t block_size = sizeof(offset_type) * 1024 * 1024 / 2; + + typedef typename stxxl::VECTOR_GENERATOR::result offset_array_type; + typedef stxxl::stream::vector_iterator2stream offset_array_it_rg; + + typedef stxxl::sequence simpleDeq; + typedef stxxl::sequence pairDeq; + typedef stxxl::sequence twoDeq; + + /** + * Comparison function for the mod0 tuples. + */ + struct less_mod0 + { + typedef skew_quint_type value_type; + + bool operator () (const value_type& a, const value_type& b) const + { + if (a.second == b.second) + return a.fourth < b.fourth; + else + return a.second < b.second; + } + + static value_type min_value() { return value_type::min_value(); } + static value_type max_value() { return value_type::max_value(); } + }; + + /** + * Counter for creating tuple indexes for example. + */ + template + struct counter + { + typedef ValueType value_type; + + value_type cnt; + + counter() : cnt(0) { } + + const value_type& operator * () const + { + return cnt; + } + + counter& operator ++ () + { + ++cnt; + return *this; + } + + bool empty() const + { + return false; + } + }; + + /** + * Compares quadruples with respect to the first component. + */ + struct less_quad_2nd + { + typedef skew_quad_type value_type; + + bool operator () (const skew_quad_type& a, const skew_quad_type& b) const + { + return a.second < b.second; + } + + static value_type min_value() { return value_type::min_value(); } + static value_type max_value() { return value_type::max_value(); } + }; + + /** + * Compares five-tuples with respect to the second component. + */ + struct less_quint_2nd + { + typedef skew_quint_type value_type; + + bool operator () (const value_type& a, const value_type& b) const + { + return a.second < b.second; + } + + static value_type min_value() { return value_type::min_value(); } + static value_type max_value() { return value_type::max_value(); } + }; + + /** + * Put the (0 mod 2) [which are the 1,2 mod 3 tuples] tuples at the begin. + */ + struct less_skew + { + typedef skew_pair_type value_type; + + bool operator () (const value_type& a, const value_type& b) const + { + if ((a.first & 1) == (b.first & 1)) + return a.first < b.first; + else + return (a.first & 1) < (b.first & 1); + } + + static value_type min_value() { return value_type::min_value(); } + static value_type max_value() { return value_type::max_value(); } + }; + + /** + * Compare two pairs by their first component. + */ + struct mod12Comparator + { + typedef skew_pair_type value_type; + + bool operator () (const value_type& a, const value_type& b) const + { + return a.first < b.first; + } + + value_type min_value() const + { + return value_type(std::numeric_limits::min(), std::numeric_limits::min()); + } + + value_type max_value() const + { + return value_type(std::numeric_limits::max(), std::numeric_limits::max()); + } + }; + + /** + * Concatenates two streams as streamA '+' streamB containing pairs. + */ + template + class concat + { + public: + typedef StreamType value_type; + + private: + StreamA& A; + StreamB& B; + + public: + concat(StreamA& A_, StreamB& B_) : A(A_), B(B_) + { + assert(!A.empty()); + assert(!B.empty()); + } + + const value_type& operator * () const + { + if (empty()) + throw std::runtime_error("operator()* error"); + if (!A.empty()) + return *A; + return *B; + } + + concat& operator ++ () + { + assert(!empty()); + + if (!A.empty()) + ++A; + else if (!B.empty()) + ++B; + + return *this; + } + + bool empty() const + { + return ((A.empty()) && (B.empty())); + } + }; + + /** + * Sort skew_quad datatype. + */ + template + struct less_quad + { + typedef typename stxxl::tuple value_type; + + bool operator () (const value_type& a, const value_type& b) const + { + if (a.second == b.second) { + if (a.third == b.third) + return a.fourth < b.fourth; + else + return a.third < b.third; + } + else { + return a.second < b.second; + } + } + + static value_type min_value() { return value_type::min_value(); } + static value_type max_value() { return value_type::max_value(); } + }; + + /// Skew naming. + + /** + * Check, if last three components of two quads are equal. + */ + template + static inline bool quad_eq(const quad_type& a, const quad_type& b) + { + return (a.second == b.second) && (a.third == b.third) && (a.fourth == b.fourth); + } + + /** + * Check overlapping of two triples in case of non-equality. + */ + template + static inline char quad_neq(const quad_type& a, const quad_type& b) + { + if ((a.second == b.second) && (a.third == b.third)) + return 2; + else if (a.second == b.second) + return 1; + else + return 0; + } + + /** + * Naming pipe for the conventional skew algorithm without discarding. + */ + template + class naming + { + public: + typedef typename Input::value_type quad_type; + typedef skew_pair_type value_type; + + private: + Input& A; + bool& unique; + offset_type lexname; + quad_type prev; + skew_pair_type result; + + simpleDeq* LCPn; + + public: + naming(Input& A_, bool& unique_, simpleDeq* lcp_names) : A(A_), unique(unique_), lexname(0) + { + assert(!A.empty()); + unique = true; + + LCPn = lcp_names; + prev = *A; + LCPn->push_back(0); // insert zero sentinel to hold LCPn[0] = 0 + + result.first = prev.first; + result.second = lexname; + } + + const value_type& operator * () const + { + return result; + } + + naming& operator ++ () + { + assert(!A.empty()); + + ++A; + if (A.empty()) return *this; + + quad_type curr = *A; + + if (!quad_eq(prev, curr)) { + ++lexname; + LCPn->push_back(quad_neq(prev, curr)); + } + else { + if (!A.empty() && curr.second != offset_type(0)) { + LCPn->push_back(3); + unique = false; + } + } + + result.first = curr.first; + result.second = lexname; + + prev = curr; + return *this; + } + + bool empty() const + { + return A.empty(); + } + }; + + /// Pipelining classes. + + /** + * Create tuples until one of the input streams are empty. + */ + template + class make_pairs + { + public: + typedef skew_pair_type value_type; + + private: + InputA& A; + InputB& B; + value_type result; + + public: + make_pairs(InputA& a, InputB& b) + : A(a), B(b) + { + assert(!A.empty()); + assert(!B.empty()); + if (!empty()) + result = value_type(*A, *B + add_alphabet); + } + + const value_type& operator * () const + { + return result; + } + + make_pairs& operator ++ () + { + assert(!A.empty()); + assert(!B.empty()); + + ++A; + ++B; + + if (!A.empty() && !B.empty()) + result = value_type(*A, *B + add_alphabet); + + return *this; + } + + bool empty() const + { + return (A.empty() || B.empty()); + } + }; + + /** + * Collect three characters t_i, t_{i+1}, t_{i+2} beginning at the index i. + * Since we need at least one unique endcaracter, we free the first characters, + * i.e. we map (t_i) -> (i,t_i,t_{i+1},t_{i+2}). + * + * \param Input holds all characters t_i from input string t. + * \param alphabet_type + * \param add_alphabet + */ + template + class make_quads + { + public: + typedef stxxl::tuple value_type; + + private: + Input& A; + value_type current; + offset_type counter; + unsigned int z3z; // = counter mod 3, ("+",Z/3Z) is cheaper than '%' + bool finished; + + offset_array_type& backup; + + public: + make_quads(Input& data_in_, offset_array_type& backup_) + : A(data_in_), + current(0, 0, 0, 0), + counter(0), + z3z(0), + finished(false), + backup(backup_) + { + assert(!A.empty()); + + current.first = counter; + current.second = (*A).second + add_alphabet; + ++A; + + if (!A.empty()) { + current.third = (*A).second + add_alphabet; + ++A; + } + else { + current.third = 0; + current.fourth = 0; + } + + if (!A.empty()) + current.fourth = (*A).second + add_alphabet; + else + current.fourth = 0; + } + + const value_type& operator * () const + { + return current; + } + + make_quads& operator ++ () + { + assert(!A.empty() || !finished); + + if (current.second != offset_type(0)) + backup.push_back(current.second); + + if (++z3z == 3) z3z = 0; + + current.first = ++counter; + current.second = current.third; + current.third = current.fourth; + + if (!A.empty()) + ++A; + + if (!A.empty()) + current.fourth = (*A).second + add_alphabet; + else + current.fourth = 0; + + if ((current.second == offset_type(0)) && (z3z != 1)) + finished = true; + + return *this; + } + + bool empty() const + { + return (A.empty() && finished); + } + }; + + /** + * Drop 1/3 of the input, more exactly the offsets at positions (0 mod 3). + * Index begins with 0. + */ + template + class extract_mod12 + { + public: + typedef typename Input::value_type value_type; + + private: + Input& A; + offset_type counter; + offset_type output_counter; + value_type result; + + public: + extract_mod12(Input& A_) : A(A_), counter(0), output_counter(0) + { + assert(!A.empty()); + ++A, ++counter; // skip 0 = mod0 offset + if (!A.empty()) { + result = *A; + result.first = output_counter; + } + } + + const value_type& operator * () const + { + return result; + } + + extract_mod12& operator ++ () + { + assert(!A.empty()); + + ++A, ++counter, ++output_counter; + + if (!A.empty() && (counter % 3) == 0) + ++A, ++counter; // skip mod0 offsets + + if (!A.empty()) { + result = *A; + result.first = output_counter; + } + + return *this; + } + + bool empty() const + { + return A.empty(); + } + }; + + /// Basis for (Batched) Range Minimum Queries (RMQ) construction. + + /** + * Sparse Table construction based on "Bender, M. A., and Farach-Colton, M. + * The LCA problem revisited (2000)", that creates a table of size n log n for + * every minimum in 'power-of-two'-ranges and allows to answer an RMQ(i,j) + * in O(1) by simple table lookups afterwards. + */ + class sparseTable + { + private: + std::vector > QTable; + + public: + sparseTable(std::vector& fieldVector) + { + std::size_t dimI = fieldVector.size(); // y-Dimension of QTable + std::size_t dimK = floor(log2(dimI)) + 1; // x-Dimension of QTable + createQTable(fieldVector, dimI, dimK); + } + + void createQTable(std::vector& field, std::size_t dimI, std::size_t dimK) + { + assert(dimI > 0); + assert(dimK > 0); + + std::size_t iLimit = dimI - 1; + std::size_t kLimit = dimK - 1; + std::size_t magicCounter = 0; + + QTable.push_back(std::vector()); + std::vector& tempVector = QTable[QTable.size() - 1]; + tempVector.reserve(iLimit); + + for (std::size_t i = 0; i <= iLimit; ++i) + tempVector.push_back(field[i]); + + for (std::size_t k = 0; k < kLimit; ++k) { + QTable.push_back(std::vector()); + std::vector& tempVector = QTable[QTable.size() - 1]; + tempVector.reserve(dimI - (0 + (1 << k))); + + magicCounter += (1 << k); + for (std::size_t i = 0; i + (1 << k) < dimI; ++i) { + if (QTable[k][i] <= QTable[k][i + (1 << k)]) + tempVector.push_back(QTable[k][i]); + else + tempVector.push_back(QTable[k][i + (1 << k)]); + + if (i == (iLimit - magicCounter)) + break; + } + } + } + + offset_type query(offset_type I, offset_type J) + { + std::size_t i = I; + std::size_t j = J; + std::size_t k = floor(log2(j - i + 1)); + offset_type r = QTable[k][i]; + offset_type s = QTable[k][j - (1 << k) + 1]; + + if (r <= s) return r; + else return s; + } + + void clear() + { + QTable.clear(); + } + }; + + /** + * This class uses the sparseTable construction to answer batched RMQs. + * First: calculate number_of_pages and page borders. + * Second: split up sequence of RMQs (id, i, j) into two parts based + * on page borders and sort splitted RMQs. + * Third: build up minBorderArray. + * Fourth: sort and answer RMQs with respect to their id. + * + * \param Stream1 holds a reference to a sequence of values the RMQs are performed on. + * \param Stream2 holds a reference to a sequence of RMQs. + */ + template + class sparseTableAlgo + { + typedef leftRmqComparator left_cmp; + typedef rightRmqComparator right_cmp; + typedef finalPairComparator final_cmp; + + typedef stxxl::sorter left_sorter_type; + typedef stxxl::sorter right_sorter_type; + typedef stxxl::sorter final_sorter_type; + + left_sorter_type left_sorter; + right_sorter_type right_sorter; + final_sorter_type collective_sorter; + + private: + std::vector minBorderArray; + offset_type span, end_part, numberOfPages; + + // Compare min of page k with last minBorderArray entries + offset_type getArrayMin(offset_type pageMin, offset_type k, offset_type tmpK) + { + offset_type min = pageMin; + offset_type lastPages = k - 1 - tmpK; + + if (lastPages > offset_type(0)) { + for (offset_type p = 1; p <= lastPages; ++p) { + if (min > minBorderArray[k - p]) + min = minBorderArray[k - p]; + } + } + return min; + } + + public: + sparseTableAlgo() + : left_sorter(left_cmp(), ram_use / 6), + right_sorter(right_cmp(), ram_use / 6), + collective_sorter(final_cmp(), ram_use / 6) { } + + // compute numberOfPages and their page-size (span) + void initialize(offset_type lengthOfVector) + { + offset_type M = (offset_type(ram_use / 2) / sizeof(offset_type)); + span = end_part = 0; + + assert(lengthOfVector > offset_type(0)); + + if (lengthOfVector >= offset_type((ram_use / 2) / sizeof(offset_type))) + span = 10000; + + do { + // space inequation: M - c >= v + v*log_2(v) + n/v + if ((M - (span + 1) - ((span + 1) * log2(span + 1)) - (lengthOfVector / (span + 1))) > 0) + ++span; + else + break; + } while (span < lengthOfVector); + + assert(span > offset_type(0)); + + offset_type tmp = (offset_type)lengthOfVector / span; + if ((lengthOfVector % span) != 0) { + end_part = lengthOfVector - (tmp * span); + numberOfPages = tmp + 1; + } + else { + numberOfPages = tmp; + } + } + + // split up RMQs (id, i, j)) into two parts + void splitAndSortRMQ(Stream2& pair_stream) + { + intPair temp; + offset_type left, leftBorder, right, rightBorder, id, tmpK; + bool finishedI; + + while (!pair_stream.empty()) { + temp = *pair_stream; + id = temp.id; + left = temp.i; + right = temp.j; + + finishedI = 0; + tmpK = 0; + leftBorder = 0; + rightBorder = span - 1; + + // i := left, j := right, | := left or right border, *|* := currently considered border + + for (offset_type k = 0; k < numberOfPages; ++k) { + // find beginning of RMQ (id, i, j) + if (left >= leftBorder && left <= rightBorder && finishedI == 0) { + // (trivial) case: ...*|*..i..j..*|*... + // => push leftRMQ(id, relative_i, relative_j, k) into leftRMQSorter + if (right >= leftBorder && right <= rightBorder) { + left_sorter.push(leftRmq(id, (left - leftBorder), (right - leftBorder), k)); + finishedI = 1; + break; + } + else { // case: ...|..i..*|*... => push leftRMQ(id, relative_i, relative_j, k) into leftRMQSorter + left_sorter.push(leftRmq(id, (left - leftBorder), (rightBorder - leftBorder), k)); + finishedI = 1; + tmpK = k; + + assert(numberOfPages > offset_type(1)); + + leftBorder = (rightBorder + 1); + if ((k == offset_type(numberOfPages - 2)) && (end_part > offset_type(0))) + rightBorder += end_part; + else + rightBorder += span; + + continue; + } + } + + // case: *|*.....*|*..j..|... + // => "empty" page, do nothing and keep on walking + + // case: *|*..j..|.....|.....| + // => push rightRMQ(id, relative_i, relative_j, k, tmpK) into rightRMQSorter + if (right >= leftBorder && right <= rightBorder && finishedI == 1) { + right_sorter.push(rightRmq(id, 0, (right - leftBorder), k, tmpK)); + break; + } + + assert(numberOfPages > offset_type(1)); + + leftBorder = (rightBorder + 1); + if ((k == offset_type(numberOfPages - 2)) && (end_part > offset_type(0))) + rightBorder += end_part; + else + rightBorder += span; + } + ++pair_stream; + } + left_sorter.sort(); + right_sorter.sort(); + } + + void answerTuple(Stream1& int_stream) + { + offset_type temp, min, left_min, right_min, leftBorder, rightBorder, page_min; + std::vector tempVector; + + leftBorder = 0; + rightBorder = span - 1; + + // build up minBorderArray + for (offset_type n = 0; n < numberOfPages; ++n) { + min = std::numeric_limits::max(); + + for (offset_type i = leftBorder; i <= rightBorder; ++i) { + assert(!int_stream.empty()); + + temp = *int_stream; + tempVector.push_back(temp); + + if (temp < min) + min = temp; + + if (i <= rightBorder) { + assert(!int_stream.empty()); + ++int_stream; + } + } + + minBorderArray.push_back(min); + + // create sparseoffset_typeable of tempVector + sparseTable myTable(tempVector); + + while (!left_sorter.empty() && left_sorter->k <= n) { + // getMin(i, j, k, tmpK, vector) + left_min = myTable.query(left_sorter->i, left_sorter->j); + + collective_sorter.push(finalPair(left_sorter->id, left_min)); + ++left_sorter; + } + + while (!right_sorter.empty() && right_sorter->k <= n) { + // getMin(i, j, k, tmpK, vector) + page_min = myTable.query(right_sorter->i, right_sorter->j); + + // mind previous minima in minBorderArray + right_min = getArrayMin(page_min, right_sorter->k, right_sorter->tmpK); + + collective_sorter.push(finalPair(right_sorter->id, right_min)); + ++right_sorter; + } + + tempVector.clear(); + myTable.clear(); + + leftBorder = (rightBorder + 1); + if ((n == offset_type(numberOfPages - 2)) && (end_part > offset_type(0))) + rightBorder += end_part; + else + rightBorder += span; + } + left_sorter.finish_clear(); + right_sorter.finish_clear(); + } + + void answerRMQ(simpleDeq& resultDeq) + { + finalPair tmp; + offset_type id, min; + + collective_sorter.sort(); // sort by their id's + + while (!collective_sorter.empty()) { + id = collective_sorter->id; + min = collective_sorter->min; + + if (collective_sorter.size() > 1) + ++collective_sorter; + + if (id == collective_sorter->id) { // equal id's + if (min >= collective_sorter->min) + resultDeq.push_back(collective_sorter->min); + else + resultDeq.push_back(min); + + if (collective_sorter.size() >= 1) + ++collective_sorter; + } + else { // unequal id's + resultDeq.push_back(min); + } + } + collective_sorter.finish_clear(); + minBorderArray.clear(); + } + }; + + /** + * Construct the lcp array by: + * \param lcpn defined as the overlapping of two lexicographical adjacent triples. + * \param lcp12 defined as the lcp array of the last recursive step of dc3-lcp. + * \param ISA1('old') defined as the inverse suffix array of the i%3==1 triples of the last recursive step of dc3. + * \param ISA2('old') defined as the inverse suffix array of the i%3==2 triples of the last recursive step of dc3. + * \param SA12('old') defined as the suffix array of the last recursive step of dc3. + */ + class build_lcp + { + private: + typedef l3Tuple l3_type; + typedef innerTuple inner_type; + typedef two_tuple two_tuple_type; + typedef pos_pair pos_pair_type; + + typedef l3TupleComparator l3Tuple_cmp; + typedef innerTupleComparator innerTuple_cmp; + typedef PairComparator pair_cmp; + + typedef stxxl::sorter l3_tuple_type; + typedef stxxl::sorter inner_tuple_type; + typedef stxxl::sorter pair_type; + + typedef typename simpleDeq::stream simpleDeqStream; + typedef typename pairDeq::stream pairDeqStream; + typedef typename twoDeq::stream twoDeqStream; + + //typedef single_concat s_concatenation; + typedef concat s_concatenation; + + simpleDeq l1Deq, l2Deq, l3Deq; + simpleDeq* lcpn_ptr, * isa1_ptr, * isa2_ptr, * sa12_ptr; + simpleDeqStream* l1_ptr, * l2_ptr, * l3_ptr; + + pairDeq l2RMQ; + twoDeq l3TempDeq; + + build_lcp* lcp12_ptr; + + bool finished_l2, blank; + + offset_type countl2; + offset_type result; + + public: + build_lcp(simpleDeq* lcpn, build_lcp* lcp12, simpleDeq* ISA1, simpleDeq* ISA2, simpleDeq* SA_12) + : finished_l2(false), blank(false), countl2(0) + { + lcpn_ptr = lcpn; + lcp12_ptr = lcp12; + isa1_ptr = ISA1; + isa2_ptr = ISA2; + sa12_ptr = SA_12; + + l1_ptr = NULL; + } + + void saveL1(char l) + { + l1Deq.push_back(l); + } + + void saveRMQ(offset_type r_i, offset_type r_j) + { + if (lcp12_ptr != NULL) { + if (r_j > offset_type(0)) + r_j = r_j - offset_type(1); + + assert(lcpn_ptr->size() >= r_i); + assert(lcpn_ptr->size() >= r_j); + + if (r_i <= r_j) + l2RMQ.push_back(intPair(countl2, r_i, r_j)); + else + l2RMQ.push_back(intPair(countl2, r_j, r_i)); + + ++countl2; + } + } + + void finalize() + { + if (l1_ptr != NULL) return; + + l1_ptr = new simpleDeqStream(l1Deq); + + if (lcp12_ptr != NULL) { + pairDeqStream rmqStream = l2RMQ.get_stream(); + + sparseTableAlgo sp_algo; + sp_algo.initialize(lcpn_ptr->size()); // |lcpn| == |lcp12| + sp_algo.splitAndSortRMQ(rmqStream); + sp_algo.answerTuple(*lcp12_ptr); + sp_algo.answerRMQ(l2Deq); + } + delete lcp12_ptr; + lcp12_ptr = NULL; + + l2_ptr = new simpleDeqStream(l2Deq); + + finished_l2 = true; + answerL3(); + } + + void preprocessL3(offset_type r_i, offset_type r_j) + { + l3TempDeq.push_back(two_tuple(r_i, r_j)); + } + + void answerL3() + { + assert(finished_l2); + + pairDeq rmqDeq; + + if (l2Deq.size() == 0) { + offset_type id = 0; + twoDeqStream l3Stream = l3TempDeq.get_stream(); + + while (!l3Stream.empty()) { + two_tuple tmp = *l3Stream; + offset_type& r_i = tmp.first; + offset_type& r_j = tmp.second; + + if ((r_i > offset_type(0)) && (r_j > offset_type(0))) { + r_j = r_j - offset_type(1); + if (r_i >= offset_type(lcpn_ptr->size()) || r_j >= offset_type(lcpn_ptr->size())) + rmqDeq.push_back(intPair(id, 0, 0)); + else if (r_i <= r_j) + rmqDeq.push_back(intPair(id, r_i, r_j)); + else + rmqDeq.push_back(intPair(id, r_j, r_i)); + } + else { + rmqDeq.push_back(intPair(id, 0, 0)); + } + ++l3Stream; + ++id; + } + + pairDeqStream rmqStream = rmqDeq.get_stream(); + simpleDeqStream lcpnStream = lcpn_ptr->get_stream(); + + sparseTableAlgo sp_algo; + sp_algo.initialize(lcpn_ptr->size()); // |lcpn| == |lcp12| + sp_algo.splitAndSortRMQ(rmqStream); + sp_algo.answerTuple(lcpnStream); + sp_algo.answerRMQ(l3Deq); + } + else { + simpleDeqStream l2Stream = l2Deq.get_stream(); + twoDeqStream l3Stream = l3TempDeq.get_stream(); + + l3_tuple_type l3_tuple_sorter(l3Tuple_cmp(), ram_use, ram_use / 2); + + offset_type id = 0; + + while (!l3Stream.empty()) { + two_tuple tmp = *l3Stream; + + offset_type& r_i = tmp.first; + offset_type& r_j = tmp.second; + + if (r_i > offset_type(0) && r_j > offset_type(0)) { + l3_tuple_sorter.push(l3_type(id, 0, r_i - 1, *l2Stream)); // (id, k, r_i - 1, l2) + l3_tuple_sorter.push(l3_type(id, 1, r_j - 1, *l2Stream)); // (id, k, r_j - 1, l2) + } + else { + rmqDeq.push_back(intPair(id, 0, 0)); // trivial RMQ + } + ++l2Stream; + ++l3Stream; + ++id; + } + + l3_tuple_sorter.sort(); + inner_tuple_type inner_tuple_sorter(innerTuple_cmp(), ram_use / 2, ram_use / 2); + + /// Compute SA12[...] part. + + { + simpleDeqStream sa12Stream = sa12_ptr->get_stream(); + offset_type flag = 0; + + while (!l3_tuple_sorter.empty()) { + l3_type tmp = *l3_tuple_sorter; // tmp = (id, k, r, l) + + while (flag < tmp.third) { + if (!sa12Stream.empty()) + ++sa12Stream; + + ++flag; + } + + inner_tuple_sorter.push(inner_type(tmp.first, tmp.second, (*sa12Stream + tmp.fourth))); + ++l3_tuple_sorter; + } + + l3_tuple_sorter.finish_clear(); + inner_tuple_sorter.sort(); + } + + /// Compute ISA[...] part. + + simpleDeqStream isa1Stream = isa1_ptr->get_stream(); + simpleDeqStream isa2Stream = isa2_ptr->get_stream(); + + s_concatenation isa12Stream(isa1Stream, isa2Stream); + pair_type isa_sorter(pair_cmp(), ram_use / 2, ram_use / 2); + + offset_type add = 0; + + while (!inner_tuple_sorter.empty()) { + inner_type tmp = *inner_tuple_sorter; // tmp (id, k, r) + + while (add < tmp.third) { + if (!isa12Stream.empty()) + ++isa12Stream; + + ++add; + } + + if (tmp.second == 1) { + if (tmp.third <= offset_type(sa12_ptr->size() - 1)) + isa_sorter.push(pos_pair_type(tmp.first, tmp.second, (*isa12Stream - 1))); + else + isa_sorter.push(pos_pair_type(tmp.first, tmp.second, 0)); + } + else { + if (tmp.third <= offset_type(sa12_ptr->size() - 1)) + isa_sorter.push(pos_pair_type(tmp.first, tmp.second, *isa12Stream)); + else + isa_sorter.push(pos_pair_type(tmp.first, tmp.second, 0)); + } + + ++inner_tuple_sorter; + } + + inner_tuple_sorter.finish_clear(); + isa_sorter.sort(); + + delete sa12_ptr; + + while (!isa_sorter.empty()) { + pos_pair_type tmp1 = *isa_sorter; // id, r_i, r_j + ++isa_sorter; + pos_pair_type tmp2 = *isa_sorter; + + if (tmp1.third <= tmp2.third) + rmqDeq.push_back(intPair(tmp1.first, tmp1.third, tmp2.third)); + else + rmqDeq.push_back(intPair(tmp1.first, tmp2.third, tmp1.third)); + + ++isa_sorter; + } + + isa_sorter.finish_clear(); + + pairDeqStream rmqStream = rmqDeq.get_stream(); + simpleDeqStream lcpnStream = lcpn_ptr->get_stream(); + + sparseTableAlgo sp_algo; + sp_algo.initialize(lcpn_ptr->size()); + sp_algo.splitAndSortRMQ(rmqStream); + sp_algo.answerTuple(lcpnStream); + sp_algo.answerRMQ(l3Deq); + } // else + + delete lcpn_ptr; + + l3_ptr = new simpleDeqStream(l3Deq); + + if (!l2_ptr->empty()) + result = *(*l1_ptr) + (3 * *(*l2_ptr)) + *(*l3_ptr); + else + result = *(*l1_ptr) + *(*l3_ptr); + } //answerL3() + + const offset_type& operator * () const + { + return result; + } + + build_lcp& operator ++ () + { + assert(!empty()); + assert(!l1_ptr->empty()); + assert(!l3_ptr->empty()); + + if (!l2_ptr->empty()) + ++(*l2_ptr); + + ++(*l1_ptr); + ++(*l3_ptr); + if (!l1_ptr->empty() && !l3_ptr->empty()) { + if (!l2_ptr->empty()) + result = *(*l1_ptr) + (3 * *(*l2_ptr)) + *(*l3_ptr); + else + result = *(*l1_ptr) + *(*l3_ptr); + } + else { + blank = true; + + assert(l1_ptr != NULL && l2_ptr != NULL && l3_ptr != NULL); + delete l1_ptr; + delete l2_ptr; + delete l3_ptr; + } + + return *this; + } + + bool empty() const + { + return blank; + } + }; //build_lcp() + + /** + * Create the suffix array and the lcp array from the current sub problem + * by simple comparison-based merging. More precisely: compare characters(out of + * text t) and ranks(out of ISA12) of the following parameter constellation: + * + * \param Mod0 5-tuple (quint): + * \param Mod1 4-tuple (quad): + * \param Mod2 5-tuple (quint): + */ + template + class merge_sa_lcp + { + public: + typedef offset_type value_type; + + private: + Mod0& A; + Mod1& B; + Mod2& C; + + skew_quint_type s0; + skew_quad_type s1; + skew_quint_type s2; + + int selected; + + bool exists[3]; + + offset_type index; + offset_type merge_result; + + offset_type last1_winner; + offset_type last2_winner; + + skew_quint_type last_s0; + skew_quad_type last_s1; + skew_quint_type last_s2; + + offset_type last_type; + offset_type bound; + + build_lcp* b_lcp; + + bool cmp_mod12() + { + return s1.second < s2.second; + } + + bool cmp_mod02() + { + if (s0.second == s2.third) { + if (s0.third == s2.fourth) + return s0.fifth < s2.fifth; + else + return s0.third < s2.fourth; + } + else { + return s0.second < s2.third; + } + } + + bool cmp_mod01() + { + if (s0.second == s1.third) + return s0.fourth < s1.fourth; + else + return s0.second < s1.third; + } + + /// Comparison part of merge. + + char l12_construction0(offset_type c1, offset_type c2) + { + if (last_type == offset_type(0)) { + if (last1_winner == c1) { + if (last2_winner == c2) { + b_lcp->saveRMQ(last_s0.fifth, s0.fifth); + b_lcp->preprocessL3(last_s0.fifth, s0.fifth); + return 2; + } + else { + b_lcp->saveRMQ(0, 0); + b_lcp->preprocessL3(0, 0); + return 1; + } + } + else { + b_lcp->saveRMQ(0, 0); + b_lcp->preprocessL3(0, 0); + return 0; + } + } + else if (last_type == offset_type(1)) { + if (last1_winner == c1) { + b_lcp->saveRMQ(last_s1.fourth, s0.fourth); + b_lcp->preprocessL3(last_s1.fourth, s0.fourth); + return 1; + } + else { + b_lcp->saveRMQ(0, 0); + b_lcp->preprocessL3(0, 0); + return 0; + } + } + else { + if (last1_winner == c1) { + if (last2_winner == c2) { + b_lcp->saveRMQ(last_s2.fifth, s0.fifth); + b_lcp->preprocessL3(last_s2.fifth, s0.fifth); + return 2; + } + else { + b_lcp->saveRMQ(0, 0); + b_lcp->preprocessL3(0, 0); + return 1; + } + } + else { + b_lcp->saveRMQ(0, 0); + b_lcp->preprocessL3(0, 0); + return 0; + } + } + } + + bool l12_construction1(offset_type c1) + { + if (last_type == offset_type(0)) { + if (last1_winner == c1) { + b_lcp->saveRMQ(last_s0.fourth, s1.fourth); + b_lcp->preprocessL3(last_s0.fourth, s1.fourth); + return 1; + } + else { + b_lcp->saveRMQ(0, 0); + b_lcp->preprocessL3(0, 0); + return 0; + } + } + else { // i.e. S1-S1 or S2-S1 + if (last_type == offset_type(1)) { + b_lcp->saveRMQ(s1.second - 1, s1.second); + b_lcp->preprocessL3(last_s1.second, s1.second); + } + else { + b_lcp->saveRMQ(s1.second - 1, s1.second); + b_lcp->preprocessL3(last_s2.second, s1.second); + } + return 0; + } + } + + char l12_construction2(offset_type c1, offset_type c2) + { + if (last_type == offset_type(0)) { + if (last1_winner == c1) { + if (last2_winner == c2) { + b_lcp->saveRMQ(last_s0.fifth, s2.fifth); + b_lcp->preprocessL3(last_s0.fifth, s2.fifth); + return 2; + } + else { + b_lcp->saveRMQ(0, 0); + b_lcp->preprocessL3(0, 0); + return 1; + } + } + else { + b_lcp->saveRMQ(0, 0); + b_lcp->preprocessL3(0, 0); + return 0; + } + } + else { // i.e. S1-S2 or S2-S2 + if (last_type == offset_type(1)) { + b_lcp->saveRMQ(s2.second - 1, s2.second); + b_lcp->preprocessL3(last_s1.second, s2.second); + } + else { + b_lcp->saveRMQ(s2.second - 1, s2.second); + b_lcp->preprocessL3(last_s2.second, s2.second); + } + return 0; + } + } + + void get012() + { + if (cmp_mod01()) { + if (cmp_mod02()) { + selected = 0; + merge_result = s0.first; + + b_lcp->saveL1(l12_construction0(s0.second, s0.third)); + last1_winner = s0.second; + last2_winner = s0.third; + + last_type = 0; + last_s0 = s0; + } + else { + selected = 2; + merge_result = s2.first; + + b_lcp->saveL1(l12_construction2(s2.third, s2.fourth)); + last1_winner = s2.third; + last2_winner = s2.fourth; + + last_type = 2; + last_s2 = s2; + } + } + else { + if (cmp_mod12()) { + selected = 1; + merge_result = s1.first; + + b_lcp->saveL1(l12_construction1(s1.third)); + last1_winner = s1.third; + + last_type = 1; + last_s1 = s1; + } + else { + selected = 2; + merge_result = s2.first; + + b_lcp->saveL1(l12_construction2(s2.third, s2.fourth)); + last1_winner = s2.third; + last2_winner = s2.fourth; + + last_type = 2; + last_s2 = s2; + } + } + } + + void get01() + { + if (cmp_mod01()) { + selected = 0; + merge_result = s0.first; + + b_lcp->saveL1(l12_construction0(s0.second, s0.third)); + last1_winner = s0.second; + last2_winner = s0.third; + + last_type = 0; + last_s0 = s0; + } + else { + selected = 1; + merge_result = s1.first; + + b_lcp->saveL1(l12_construction1(s1.third)); + last1_winner = s1.third; + + last_type = 1; + last_s1 = s1; + } + } + + void get12() + { + if (cmp_mod12()) { + selected = 1; + merge_result = s1.first; + + b_lcp->saveL1(l12_construction1(s1.third)); + last1_winner = s1.third; + + last_type = 1; + last_s1 = s1; + } + else { + selected = 2; + merge_result = s2.first; + + b_lcp->saveL1(l12_construction2(s2.third, s2.fourth)); + last1_winner = s2.third; + last2_winner = s2.fourth; + + last_type = 2; + last_s2 = s2; + } + } + + void get02() + { + if (cmp_mod02()) { + selected = 0; + merge_result = s0.first; + + b_lcp->saveL1(l12_construction0(s0.second, s0.third)); + last1_winner = s0.second; + last2_winner = s0.third; + + last_type = 0; + last_s0 = s0; + } + else { + selected = 2; + merge_result = s2.first; + + b_lcp->saveL1(l12_construction2(s2.third, s2.fourth)); + last1_winner = s2.third; + last2_winner = s2.fourth; + + last_type = 2; + last_s2 = s2; + } + } + + void solve() + { + if (exists[0]) { + if (exists[1]) { + if (exists[2]) { + get012(); + } + else { + get01(); + } + } + else { + if (exists[2]) { + get02(); + } + else { + selected = 0; + merge_result = s0.first; + + b_lcp->saveL1(l12_construction0(s0.second, s0.third)); + last1_winner = s0.second; + last2_winner = s0.third; + + last_type = 0; + last_s0 = s0; + } + } + } + else { + if (exists[1]) { + if (exists[2]) { + get12(); + } + else { + selected = 1; + merge_result = s1.first; + + b_lcp->saveL1(l12_construction1(s1.third)); + last1_winner = s1.third; + + last_type = 1; + last_s1 = s1; + } + } + else { + if (exists[2]) { + selected = 2; + merge_result = s2.first; + + b_lcp->saveL1(l12_construction2(s2.third, s2.fourth)); + last1_winner = s2.third; + last2_winner = s2.fourth; + + last_type = 2; + last_s2 = s2; + } + else { + assert(false); + } + } + } + } + + public: + bool empty() const + { + return (A.empty() && B.empty() && C.empty()); + } + + merge_sa_lcp(Mod0& x1, Mod1& x2, Mod2& x3, build_lcp* lcp_ptr) + : A(x1), B(x2), C(x3), selected(-1), index(0) + { + assert(!A.empty()); + assert(!B.empty()); + assert(!C.empty()); + exists[0] = true; + exists[1] = true; + exists[2] = true; + s0 = *A; + s1 = *B; + s2 = *C; + + last1_winner = std::numeric_limits::max(); + last2_winner = std::numeric_limits::max(); + + last_type = 3; // last_type \in [0,2] + + last_s0 = s0; + last_s1 = s1; + last_s2 = s2; + + b_lcp = lcp_ptr; + + solve(); + } + + const value_type& operator * () const + { + return merge_result; + } + + merge_sa_lcp& operator ++ () + { + if (selected == 0) { + assert(!A.empty()); + ++A; + if (!A.empty()) + s0 = *A; + else + exists[0] = false; + } + else if (selected == 1) { + assert(!B.empty()); + ++B; + if (!B.empty()) + s1 = *B; + else + exists[1] = false; + } + else { + assert(!C.empty()); + assert(selected == 2); + ++C; + if (!C.empty()) + s2 = *C; + else + exists[2] = false; + } + + ++index; + if (!empty()) + solve(); + + return *this; + } + }; + + /** + * Helper function for computing the size of the 2/3 subproblem. + */ + static inline offset_type subp_size(size_type n) + { + return offset_type((n / 3) * 2 + ((n % 3) == 2)); + } + + /** + * Sort mod0-quints / mod1-quads / mod2-quints and + * run merge_sa_lcp class to merge them together. + * \param S input string pipe type. + * \param Mod1 mod1 tuples input pipe type. + * \param Mod2 mod2 tuples input pipe type. + */ + template + class build_sa + { + public: + typedef offset_type value_type; + static const unsigned int add_rank = 1; // free first rank to mark ranks beyond end of input + + private: + // Mod1 types + typedef typename stxxl::stream::use_push mod1_push_type; + typedef typename stxxl::stream::runs_creator mod1_runs_type; + typedef typename mod1_runs_type::sorted_runs_type sorted_mod1_runs_type; + typedef typename stxxl::stream::runs_merger mod1_rm_type; + + // Mod2 types + typedef typename stxxl::stream::use_push mod2_push_type; + typedef typename stxxl::stream::runs_creator mod2_runs_type; + typedef typename mod2_runs_type::sorted_runs_type sorted_mod2_runs_type; + typedef typename stxxl::stream::runs_merger mod2_rm_type; + + // Mod0 types + typedef typename stxxl::stream::use_push mod0_push_type; + typedef typename stxxl::stream::runs_creator mod0_runs_type; + typedef typename mod0_runs_type::sorted_runs_type sorted_mod0_runs_type; + typedef typename stxxl::stream::runs_merger mod0_rm_type; + + // Merge type + typedef merge_sa_lcp merge_sa_lcp_type; + + // Functions + less_mod0 c0; + less_quad_2nd c1; + less_quint_2nd c2; + + // Runs merger + mod1_rm_type* mod1_result; + mod2_rm_type* mod2_result; + mod0_rm_type* mod0_result; + + // Merger + merge_sa_lcp_type* vmerge_sa_lcp; + + // Input + S& source; + Mod1& mod_1; + Mod2& mod_2; + + // Tmp variables + offset_type t[3]; + offset_type old_t2; + offset_type old_mod2; + bool exists[3]; + offset_type mod_one; + offset_type mod_two; + + offset_type index; + + // Empty_flag + bool ready; + + // Result + value_type result; + + // lcp part + simpleDeq ISA1; + simpleDeq ISA2; + build_lcp* b_lcp; + + public: + build_sa(S& source_, Mod1& mod_1_, Mod2& mod_2_, size_type a_size, std::size_t memsize, + simpleDeq* lcp_names, build_lcp* lcp12, simpleDeq* SA_12) + : source(source_), mod_1(mod_1_), mod_2(mod_2_), index(0), ready(false) + { + assert(!source_.empty()); + + // Runs storage + + // input: ISA_1,2 from previous level + mod0_runs_type mod0_runs(c0, memsize / 4); + mod1_runs_type mod1_runs(c1, memsize / 4); + mod2_runs_type mod2_runs(c2, memsize / 4); + + while (!source.empty()) + { + exists[0] = false; + exists[1] = false; + exists[2] = false; + + if (!source.empty()) { + t[0] = *source; + ++source; + exists[0] = true; + } + + if (!source.empty()) { + assert(!mod_1.empty()); + t[1] = *source; + ++source; + mod_one = *mod_1 + add_rank; + ISA1.push_back(mod_one); + ++mod_1; // isa1 + exists[1] = true; + } + + if (!source.empty()) { + assert(!mod_2.empty()); + t[2] = *source; + ++source; + mod_two = *mod_2 + add_rank; + ISA2.push_back(mod_two); + ++mod_2; // isa2 + exists[2] = true; + } + + // Check special cases in the middle of "source" + // Cases are cx|xc cxx|cxx and cxxc|xxc + + assert(t[0] != offset_type(0)); + assert(t[1] != offset_type(0)); + assert(t[2] != offset_type(0)); + + // modX = isaX + // Mod 0 : (index0,char0,char1,mod1,mod2) + // Mod 1 : (index1,mod1,char1,mod2) + // Mod 2 : (index2,mod2) + + if (exists[2]) { // Nothing is missed + mod0_runs.push(skew_quint_type(index, t[0], t[1], mod_one, mod_two)); + mod1_runs.push(skew_quad_type(index + 1, mod_one, t[1], mod_two)); + + if (index != offset_type(0)) + mod2_runs.push(skew_quint_type((index - 1), old_mod2, old_t2, t[0], mod_one)); + } + else if (exists[1]) { // Last element missed + mod0_runs.push(skew_quint_type(index, t[0], t[1], mod_one, 0)); + mod1_runs.push(skew_quad_type(index + 1, mod_one, t[1], 0)); + + if (index != offset_type(0)) + mod2_runs.push(skew_quint_type((index - 1), old_mod2, old_t2, t[0], mod_one)); + } + else { // Only one element left + assert(exists[0]); + mod0_runs.push(skew_quint_type(index, t[0], 0, 0, 0)); + + if (index != offset_type(0)) + mod2_runs.push(skew_quint_type((index - 1), old_mod2, old_t2, t[0], 0)); + } + + old_mod2 = mod_two; + old_t2 = t[2]; + index += 3; + } + + if ((a_size % 3) == 0) { // changed + if (index != offset_type(0)) + mod2_runs.push(skew_quint_type((index - 1), old_mod2, old_t2, 0, 0)); + } + + if ((a_size % 3) == 1) { + mod_one = *mod_1 + add_rank; + ISA1.push_back(mod_one); + } + + mod0_runs.deallocate(); + mod1_runs.deallocate(); + mod2_runs.deallocate(); + + // Prepare for merging + mod0_result = new mod0_rm_type(mod0_runs.result(), less_mod0(), memsize / 5); + mod1_result = new mod1_rm_type(mod1_runs.result(), less_quad_2nd(), memsize / 5); + mod2_result = new mod2_rm_type(mod2_runs.result(), less_quint_2nd(), memsize / 5); + + // output: ISA_1,2 for next level + b_lcp = new build_lcp(lcp_names, lcp12, &ISA1, &ISA2, SA_12); + vmerge_sa_lcp = new merge_sa_lcp_type(*mod0_result, *mod1_result, *mod2_result, b_lcp); // S_0, S_1, S_2, b_lcp + + result = *(*vmerge_sa_lcp); + } + + const value_type& operator * () const + { + return result; + } + + build_sa& operator ++ () + { + assert(vmerge_sa_lcp != 0 && !vmerge_sa_lcp->empty()); + + ++(*vmerge_sa_lcp); + if (!vmerge_sa_lcp->empty()) { + result = *(*vmerge_sa_lcp); + } + else { + assert(vmerge_sa_lcp->empty()); + ready = true; + + assert(vmerge_sa_lcp != NULL); + delete vmerge_sa_lcp; + vmerge_sa_lcp = NULL; + + assert(mod0_result != NULL && mod1_result != NULL && mod2_result != NULL); + delete mod0_result; + mod0_result = NULL; + delete mod1_result; + mod1_result = NULL; + delete mod2_result; + mod2_result = NULL; + } + + return *this; + } + + bool empty() const + { + return ready; + } + + build_lcp * finalize_lcp() + { + assert(ready); // merge *must* be finished here + b_lcp->finalize(); + + return b_lcp; + } + }; + + /// The core of DC3-LCP aka skew3-lcp algorithm. + + /** + * The algorithm class calls all sub-parts of DC3-LCP from this section and collect their returns. + * + * \param Input type of the input pipe. + * \param block_size block size of an external sorter we use. + */ + template + class algorithm + { + public: + typedef offset_type value_type; + typedef typename Input::value_type alphabet_type; + + private: + typedef counter counter_stream_type; + // (t_i) -> (i,t_i) + typedef make_pairs make_pairs_input_type; + + bool finished; // used for empty() check + bool unique; // is the current quad array unique? + unsigned int rec_depth; // current recusion depth of the algorithm + + typedef mod12Comparator mod12cmp; + typedef stxxl::sorter, mod12cmp, block_size> mod12_sorter_type; + + typedef stxxl::stream::choose isa_second_type; + typedef build_sa buildSA_type; + typedef make_pairs precompute_isa_type; + + buildSA_type* out_sa; // points at final constructed suffix array + + private: + /// Recursion of dc3-lcp. + + template + buildSA_type * dc3_lcp(InputType1& p_Input) + { + // (t_i) -> (i,t_i,t_{i+1},t_{i+2}) + typedef make_quads make_quads_input_type; + + // (t_i) -> (i,t_i,t_{i+1},t_{i+2}) with i = 1,2 mod 3 + typedef extract_mod12 mod12_quads_input_type; + + // sort (i,t_i,t_{i+1},t_{i+2}) by (t_i,t_{i+1},t_{i+2}) + typedef typename stxxl::stream::sort, block_size> sort_mod12_input_type; + + // name (i,t_i,t_{i+1},t_{i+2}) -> (i,n_i) + typedef naming naming_input_type; + + unique = false; + offset_type sticking_length = 0; // holds length of current s^12 + + mod12_sorter_type m1_sorter(mod12cmp(), ram_use / 6); + mod12_sorter_type m2_sorter(mod12cmp(), ram_use / 6); + + // sorted mod1 runs -concat- sorted mod2 runs + typedef concat, mod12_sorter_type, mod12_sorter_type> concatenation; + + offset_array_type text; + + // (t_i) -> (i,t_i,t_{i+1},t_{i+2}) + make_quads_input_type quads_input(p_Input, text); + + // (t_i) -> (i,t_i,t_{i+1},t_{i+2}) with i = 1,2 mod 3 + mod12_quads_input_type mod12_quads_input(quads_input); + + // sort (i,t_i,t_{i+1},t_{i+2}) by (t_i,t_i+1},t_{i+2}) + sort_mod12_input_type sort_mod12_input(mod12_quads_input, less_quad(), ram_use / 6); + + // lcpn sequence + simpleDeq* lcp_names = new simpleDeq; + + // name (i,t_i,t_{i+1},t_{i+2}) -> (i,"n_i") + naming_input_type names_input(sort_mod12_input, unique, lcp_names); // fill lcp_names while lexnaming step + + // create (i, s^12[i]) + while (!names_input.empty()) { + const skew_pair_type& tmp = *names_input; + if (tmp.first & 1) + m2_sorter.push(tmp); + else + m1_sorter.push(tmp); + + ++names_input; + sticking_length = sticking_length + 1; + //sticking_length++; //old + } + + m1_sorter.sort(); + m2_sorter.sort(); + + if (!unique) { + ++rec_depth; + (std::cout << "lexicographical names are not unique -> recusion depth=" << rec_depth << std::endl).flush(); + + // compute s^12 := lexname[S[1 mod 3]] '+' lexname[S[2 mod 3]], (also known as reduced recursion string 'R') + concatenation stick_mod1mod2(m1_sorter, m2_sorter); + + buildSA_type* recType = dc3_lcp(stick_mod1mod2); + + // deallocate runs_creator and runs_creator + m1_sorter.finish_clear(); + m2_sorter.finish_clear(); + + --rec_depth; + (std::cout << "recusion depth=" << rec_depth << std::endl).flush(); + + counter_stream_type sa_loop_index; + precompute_isa_type sa_pairs(*recType, sa_loop_index); // => (SA12, i) + + // store beginning of mod2-tuples of s^12 in mod2_pos + offset_type special = (sticking_length != subp_size(text.size())); + offset_type mod2_pos = (subp_size(text.size()) >> 1) + (subp_size(text.size()) & 1) + special; + + mod12_sorter_type isa1_type(mod12cmp(), ram_use / 6); + mod12_sorter_type isa2_type(mod12cmp(), ram_use / 6); + + simpleDeq* SA12 = new simpleDeq; + + while (!sa_pairs.empty()) { + const skew_pair_type& tmp = *sa_pairs; // tmp.first is exactly the SA12 array + SA12->push_back(tmp.first); // save current SA^12 vector + if (tmp.first < mod2_pos) + isa1_type.push(tmp); + else + isa2_type.push(tmp); + + ++sa_pairs; + } + + isa1_type.finish(); + isa2_type.finish(); + + build_lcp* lcp12 = recType->finalize_lcp(); + + delete recType; + + offset_array_it_rg input(text.begin(), text.end()); + + // => (i, ISA) + isa1_type.sort(ram_use / 8); + isa2_type.sort(ram_use / 8); + + // pick ISA of (i, ISA) + isa_second_type isa1_(isa1_type); + isa_second_type isa2_(isa2_type); + + return new buildSA_type(input, isa1_, isa2_, text.size(), ram_use, lcp_names, lcp12, SA12); + } + // else (if unique) + (std::cout << "unique lexicographical names! " << std::endl).flush(); + + isa_second_type isa1(m1_sorter); + isa_second_type isa2(m2_sorter); + + offset_array_it_rg source(text.begin(), text.end()); + + // build lcp12[i] = 0 forall i -> use NULL + return new buildSA_type(source, isa1, isa2, text.size(), ram_use, lcp_names, NULL, NULL); + } //dc3-lcp() + + public: + algorithm(Input& data_in) : finished(false), rec_depth(0) + { + // (t_i) -> (i,t_i) + counter_stream_type dummy; + make_pairs_input_type pairs_input(dummy, data_in); + + this->out_sa = dc3_lcp(pairs_input); + } + + ~algorithm() + { + delete out_sa; + out_sa = NULL; + } + + const value_type& operator * () const + { + return *(*out_sa); + } + + algorithm& operator ++ () + { + assert(!out_sa->empty()); + + ++(*out_sa); + + if ((out_sa != NULL) && (out_sa->empty())) + finished = true; + + return *this; + } + + bool empty() const + { + return finished; + } + + build_lcp * finish_lcp() + { + return out_sa->finalize_lcp(); + } + }; // algorithm class +}; // skew class + +} // namespace algo + +// Helper to print out readable characters. +template +static inline std::string dumpC(alphabet_type c) +{ + std::ostringstream oss; + if (isalnum(c)) oss << '\'' << (char)c << '\''; + else oss << (int)c; + return oss.str(); +} + +/** + * Helper class which cuts input off an input stream at a specified length. + */ +template +class cut_stream +{ +public: + // same value type as input stream + typedef typename InputType::value_type value_type; + +protected: + // instance of input stream + InputType& m_input; + + // counter after which the stream ends + size_type m_count; + +public: + cut_stream(InputType& input, size_type count) + : m_input(input), m_count(count) { } + + const value_type& operator * () const + { + assert(m_count > 0); + return *m_input; + } + + cut_stream& operator ++ () + { + assert(!empty()); + --m_count; + ++m_input; + return *this; + } + + bool empty() const + { + return (m_count == 0) || m_input.empty(); + } +}; + +alphabet_type unary_generator() +{ + return 'a'; +} + +template +int process(const std::string& input_filename, const std::string& output_filename, + size_type sizelimit, bool text_output_flag, bool check_flag, bool input_verbatim) +{ + static const std::size_t block_size = sizeof(offset_type) * 1024 * 1024 / 2; + + typedef typename stxxl::VECTOR_GENERATOR::result alphabet_vector_type; + typedef typename stxxl::VECTOR_GENERATOR::result offset_vector_type; + + // input and output files (if supplied via command line) + stxxl::syscall_file* input_file = NULL, * output_file = NULL; + + // input and output vectors for suffix array construction + alphabet_vector_type input_vector; + + offset_vector_type output_vector; + offset_vector_type lcparray; + + // to verify lcparray with kasai's semi external algorithm + offset_vector_type checker_lcp; + + using stxxl::file; + + if (input_verbatim) { + // copy input verbatim into vector + input_vector.resize(input_filename.size()); + std::copy(input_filename.begin(), input_filename.end(), input_vector.begin()); + } + else if (input_filename == "random") { + if (sizelimit == std::numeric_limits::max()) { + std::cout << "You must provide -s for generated inputs." << std::endl; + return 1; + } + + // fill input vector with random bytes + input_vector.resize(sizelimit); + stxxl::random_number8_r rand8; + stxxl::generate(input_vector.begin(), input_vector.end(), rand8); + } + else if (input_filename == "unary") { + if (sizelimit == std::numeric_limits::max()) { + std::cout << "You must provide -s for generated inputs." << std::endl; + return 1; + } + + // fill input vector with a's + input_vector.resize(sizelimit); + stxxl::generate(input_vector.begin(), input_vector.end(), unary_generator); + } + else { + // define input file object and map input_vector to input_file (no copying) + input_file = new stxxl::syscall_file(input_filename, file::RDONLY | file::DIRECT); + alphabet_vector_type file_input_vector(input_file); + input_vector.swap(file_input_vector); + } + + if (output_filename.size()) { + // define output file object and map output_vector to output_file + output_file = new stxxl::syscall_file(output_filename, file::RDWR | file::CREAT | file::DIRECT); + offset_vector_type file_output_vector(output_file); + output_vector.swap(file_output_vector); + } + + // initialize and start I/O measurement + stxxl::stats* Stats = stxxl::stats::get_instance(); + stxxl::stats_data stats_begin(*Stats); + + // construct skew class with bufreader input type + typedef alphabet_vector_type::bufreader_type input_type; + typedef cut_stream cut_input_type; + typedef typename algo::skew::template algorithm skew_type; + + size_type size = input_vector.size(); + if (size > sizelimit) size = sizelimit; + + std::cout << "input size = " << size << std::endl; + + if (size + 3 >= std::numeric_limits::max()) { + std::cout << "error: input is too long for selected word size!" << std::endl; + return -1; + } + + input_type input(input_vector); + cut_input_type cut_input(input, size); + skew_type skew(cut_input); + + // make sure output vector has the right size + output_vector.resize(size); + lcparray.resize(size); + checker_lcp.resize(size); + + // write suffix array stream into output vector + stxxl::stream::materialize(skew, output_vector.begin(), output_vector.end()); + + typename algo::skew::build_lcp * lcp = skew.finish_lcp(); + stxxl::stream::materialize(*lcp, lcparray.begin(), lcparray.end()); + + std::cout << "output size = " << output_vector.size() << std::endl; + std::cout << (stxxl::stats_data(*Stats) - stats_begin); // print i/o statistics + + if (text_output_flag) { + std::cout << std::endl << "resulting suffix array:" << std::endl; + + for (size_type i = 0; i < output_vector.size(); i++) { + std::cout << i << " : " << output_vector[i] << " : "; + + // We need a const reference because operator[] would write data + const alphabet_vector_type& cinput = input_vector; + + for (size_type j = 0; output_vector[i] + j < cinput.size(); j++) + std::cout << dumpC(cinput[output_vector[i] + j]) << " "; + + std::cout << std::endl; + } + + std::cout << "resulting lcp array: \n"; + + for (size_type k = 0; k < lcparray.size(); ++k) + std::cout << k << " : " << dumpC(lcparray[k]) << std::endl; + } + + int ret = 0; + + if (check_flag) { + (std::cout << "checking suffix array... ").flush(); + + if (!sacheck_vectors(input_vector, output_vector)) { + std::cout << "failed!" << std::endl; + ret = -1; + } + else + std::cout << "ok." << std::endl; + + (std::cout << "checking lcp array... ").flush(); + + lcparray_stxxl_kasai(input_vector, output_vector, checker_lcp); + bool correct_lcp = true; + + for (unsigned int k = 0; k < lcparray.size(); ++k) { + if (checker_lcp[k] != lcparray[k]) { + std::cout << "failed!" << std::endl; + std::cout << k << ", " << checker_lcp[k] << " - " << lcparray[k] << std::endl; + correct_lcp = false; + ret = -2; + break; + } + } + + if (correct_lcp) + std::cout << "ok." << std::endl; + } + + // close file, but have to deallocate vector first! + + if (input_file) { + input_vector = alphabet_vector_type(); + delete input_file; + } + if (output_file) { + output_vector = offset_vector_type(); + delete output_file; + } + + return ret; +} + +int main(int argc, char* argv[]) +{ + stxxl::cmdline_parser cp; + + cp.set_description( + "DC3-LCP aka skew3-lcp algorithm for external memory suffix array and LCP array construction."); + cp.set_author( + "Jens Mehnert , \n" + "Timo Bingmann , \n" + "Daniel Feist "); + + std::string input_filename, output_filename; + size_type sizelimit = std::numeric_limits::max(); + bool text_output_flag = false; + bool check_flag = false; + bool input_verbatim = false; + unsigned wordsize = 32; + + cp.add_param_string("input", input_filename, + "Path to input file (or verbatim text).\n" + " The special inputs 'random' and 'unary' generate " + "such text on-the-fly."); + cp.add_flag('c', "check", check_flag, + "Check suffix array for correctness."); + cp.add_flag('t', "text", text_output_flag, + "Print out suffix array in readable text."); + cp.add_string('o', "output", output_filename, + "Output suffix array to given path."); + cp.add_flag('v', "verbatim", input_verbatim, + "Consider \"input\" as verbatim text to construct " + "suffix array on."); + cp.add_bytes('s', "size", sizelimit, + "Cut input text to given size," + "units are [b,kb,mb,gb], e.g. 100kb."); + cp.add_bytes('M', "memuse", ram_use, + "Amount of RAM to use, default: 1 GiB."); + cp.add_uint('w', "wordsize", wordsize, + "Set word size of suffix array to 32, 40 or 64 bit," + "default: 32-bit."); + + // process command line + if (!cp.process(argc, argv)) + return -1; + + if (wordsize == 32) + return process( + input_filename, output_filename, sizelimit, + text_output_flag, check_flag, input_verbatim); + else if (wordsize == 40) + return process( + input_filename, output_filename, sizelimit, + text_output_flag, check_flag, input_verbatim); + else if (wordsize == 64) + return process( + input_filename, output_filename, sizelimit, + text_output_flag, check_flag, input_verbatim); + else + std::cerr << "Invalid wordsize for suffix array: 32, 40 or 64 are allowed." << std::endl; + + return -1; +} diff --git a/include/stxxl/bits/common/tuple.h b/include/stxxl/bits/common/tuple.h index 56cb10bf3..721a45b5a 100644 --- a/include/stxxl/bits/common/tuple.h +++ b/include/stxxl/bits/common/tuple.h @@ -627,6 +627,22 @@ struct tuple_less2nd static value_type max_value() { return value_type::max_value(); } }; +template +struct tuple_less2nd_less1st +{ + typedef TupleType value_type; + + bool operator () (const value_type& a, const value_type& b) const + { + if (a.second == b.second) + return (a.first < b.first); + return (a.second < b.second); + } + + static value_type min_value() { return value_type::min_value(); } + static value_type max_value() { return value_type::max_value(); } +}; + namespace stream { /** diff --git a/include/stxxl/bits/common/utils.h b/include/stxxl/bits/common/utils.h index 5f6443dd2..4d6f4b1ae 100644 --- a/include/stxxl/bits/common/utils.h +++ b/include/stxxl/bits/common/utils.h @@ -199,7 +199,7 @@ typename compat::remove_const::type div_ceil(Integral n, Integral2 d) { #if 0 // ambiguous overload for std::div(unsigned_anything, unsigned_anything) - typedef __typeof__ (std::div(n, d)) div_type; + typedef __typeof__ (std::div (n, d)) div_type; div_type result = std::div(n, d); return result.quot + (result.rem != 0); #else diff --git a/include/stxxl/bits/common/winner_tree.h b/include/stxxl/bits/common/winner_tree.h index ec3187bab..9e1ae5f8b 100644 --- a/include/stxxl/bits/common/winner_tree.h +++ b/include/stxxl/bits/common/winner_tree.h @@ -189,10 +189,10 @@ class winner_tree * corresponds to the path from leaf [index] to root. If only the value of * player [index] has changed the result is a valid winner tree. * - * \param index The player whose value has changed. + * \param index The player whose value has changed. * - * \param done Set done to true if the player has been deactivated - * or removed. All games will be lost then. + * \param done Set done to true if the player has been deactivated + * or removed. All games will be lost then. */ inline void replay_on_change(unsigned int index, bool done = false) { diff --git a/include/stxxl/bits/containers/hash_map/hash_map.h b/include/stxxl/bits/containers/hash_map/hash_map.h index d94ef2d61..195842a5a 100644 --- a/include/stxxl/bits/containers/hash_map/hash_map.h +++ b/include/stxxl/bits/containers/hash_map/hash_map.h @@ -1107,7 +1107,7 @@ class hash_map : private noncopyable } }; - /* Rebuild hash-map. The desired number of buckets may be supplied. */ + /* Rebuild hash-map. The desired number of buckets may be supplied. */ void _rebuild_buckets(internal_size_type n_desired = 0) { STXXL_VERBOSE_HASH_MAP("_rebuild_buckets()"); diff --git a/include/stxxl/bits/containers/hash_map/iterator.h b/include/stxxl/bits/containers/hash_map/iterator.h index 9aa95aef8..b8f1760ab 100644 --- a/include/stxxl/bits/containers/hash_map/iterator.h +++ b/include/stxxl/bits/containers/hash_map/iterator.h @@ -245,9 +245,9 @@ class hash_map_iterator_base public: //! Advance iterator to the next value //! The next value is determined in the following way - //! - if there are remaining internal or external values in the current - //! bucket, choose the smallest among them, that is not marked as deleted - //! - otherwise continue with the next bucket + //! - if there are remaining internal or external values in the current + //! bucket, choose the smallest among them, that is not marked as deleted + //! - otherwise continue with the next bucket void find_next(bool start_prefetching = false) { // invariant: current external value is always > current internal value diff --git a/include/stxxl/bits/containers/hash_map/iterator_map.h b/include/stxxl/bits/containers/hash_map/iterator_map.h index 068b9995c..57555b3af 100644 --- a/include/stxxl/bits/containers/hash_map/iterator_map.h +++ b/include/stxxl/bits/containers/hash_map/iterator_map.h @@ -175,8 +175,8 @@ class iterator_map : private noncopyable (**it2fix).source_ = hash_map_type::src_internal; (**it2fix).node_ = node; (**it2fix).i_external_++; - if ((** it2fix).reader_) - (** it2fix).reader_->operator ++ (); + if ((**it2fix).reader_) + (**it2fix).reader_->operator ++ (); } } diff --git a/include/stxxl/bits/containers/parallel_priority_queue.h b/include/stxxl/bits/containers/parallel_priority_queue.h index 51e39bc9a..cb3be6fcf 100644 --- a/include/stxxl/bits/containers/parallel_priority_queue.h +++ b/include/stxxl/bits/containers/parallel_priority_queue.h @@ -1900,8 +1900,8 @@ class parallel_priority_queue : private noncopyable block_size, DefaultMemSize, MaxItems> > minima_type; //! allow minima tree access to internal data structures friend class ppq_local::minima_tree< - parallel_priority_queue >; + parallel_priority_queue >; //! Inverse comparison functor struct inv_compare_type diff --git a/include/stxxl/bits/io/completion_handler.h b/include/stxxl/bits/io/completion_handler.h index 83ce2a6d0..453905b12 100644 --- a/include/stxxl/bits/io/completion_handler.h +++ b/include/stxxl/bits/io/completion_handler.h @@ -90,7 +90,7 @@ class completion_handler void operator () (request* req) { if (m_ptr.get()) - (* m_ptr)(req); + (*m_ptr)(req); } }; diff --git a/include/stxxl/bits/io/request_queue_impl_worker.h b/include/stxxl/bits/io/request_queue_impl_worker.h index 1489c0c2c..9c3fe5f88 100644 --- a/include/stxxl/bits/io/request_queue_impl_worker.h +++ b/include/stxxl/bits/io/request_queue_impl_worker.h @@ -54,7 +54,7 @@ class request_queue_impl_worker : public request_queue #endif protected: - void start_thread(void* (* worker)(void*), void* arg, thread_type& t, state& s); + void start_thread(void* (*worker)(void*), void* arg, thread_type& t, state& s); void stop_thread(thread_type& t, state& s, semaphore& sem); }; diff --git a/include/stxxl/bits/mng/adaptor.h b/include/stxxl/bits/mng/adaptor.h index 2f6bab629..a7834be6a 100644 --- a/include/stxxl/bits/mng/adaptor.h +++ b/include/stxxl/bits/mng/adaptor.h @@ -135,7 +135,7 @@ class blocked_index }; #define STXXL_ADAPTOR_ARITHMETICS(pos) \ - bool operator == (const self_type& a) const \ + bool operator == (const self_type &a) const \ { \ return (a.pos == pos); \ } \ diff --git a/include/stxxl/bits/mng/block_scheduler.h b/include/stxxl/bits/mng/block_scheduler.h index 9f0c6893f..091d9d83b 100644 --- a/include/stxxl/bits/mng/block_scheduler.h +++ b/include/stxxl/bits/mng/block_scheduler.h @@ -603,7 +603,7 @@ class block_scheduler_algorithm_online_lru : public block_scheduler_algorithm swappable_block shall keep its internal_block diff --git a/include/stxxl/bits/mng/buf_istream.h b/include/stxxl/bits/mng/buf_istream.h index d466b16ca..92d18d351 100644 --- a/include/stxxl/bits/mng/buf_istream.h +++ b/include/stxxl/bits/mng/buf_istream.h @@ -71,7 +71,7 @@ class buf_istream : private noncopyable // obvious schedule //for(int_type i = 0; i < seq_length; ++i) - // prefetch_seq[i] = i; + // prefetch_seq[i] = i; // optimal schedule nbuffers = STXXL_MAX(2 * ndisks, unsigned_type(nbuffers - 1)); diff --git a/include/stxxl/bits/parallel/multiway_merge.h b/include/stxxl/bits/parallel/multiway_merge.h index a2dc47b85..619a75601 100644 --- a/include/stxxl/bits/parallel/multiway_merge.h +++ b/include/stxxl/bits/parallel/multiway_merge.h @@ -421,15 +421,15 @@ multiway_merge_3_variant(RandomAccessIteratorIterator seqs_begin, goto s210; } -#define STXXL_MERGE3CASE(a, b, c, c0, c1) \ - s ## a ## b ## c : \ - *target = *seq ## a; \ - ++target; \ - --length; \ - ++seq ## a; \ - if (length == 0) goto finish; \ - if (seq ## a c0 seq ## b) goto s ## a ## b ## c; \ - if (seq ## a c1 seq ## c) goto s ## b ## a ## c; \ +#define STXXL_MERGE3CASE(a, b, c, c0, c1) \ + s ## a ## b ## c : \ + *target = *seq ## a; \ + ++target; \ + --length; \ + ++seq ## a; \ + if (length == 0) goto finish; \ + if (seq ## a c0 seq ## b) goto s ## a ## b ## c; \ + if (seq ## a c1 seq ## c) goto s ## b ## a ## c; \ goto s ## b ## c ## a; STXXL_MERGE3CASE(0, 1, 2, <=, <=); @@ -578,12 +578,12 @@ multiway_merge_4_variant(RandomAccessIteratorIterator seqs_begin, seq2(seqs_begin[2].first, seqs_begin[2].second, comp), seq3(seqs_begin[3].first, seqs_begin[3].second, comp); -#define STXXL_DECISION(a, b, c, d) do { \ - if (seq ## d < seq ## a) goto s ## d ## a ## b ## c; \ - if (seq ## d < seq ## b) goto s ## a ## d ## b ## c; \ - if (seq ## d < seq ## c) goto s ## a ## b ## d ## c; \ - goto s ## a ## b ## c ## d; \ -} \ +#define STXXL_DECISION(a, b, c, d) do { \ + if (seq ## d < seq ## a) goto s ## d ## a ## b ## c; \ + if (seq ## d < seq ## b) goto s ## a ## d ## b ## c; \ + if (seq ## d < seq ## c) goto s ## a ## b ## d ## c; \ + goto s ## a ## b ## c ## d; \ +} \ while (0) if (seq0 <= seq1) @@ -608,16 +608,16 @@ multiway_merge_4_variant(RandomAccessIteratorIterator seqs_begin, STXXL_DECISION(2, 1, 0, 3); } -#define STXXL_MERGE4CASE(a, b, c, d, c0, c1, c2) \ - s ## a ## b ## c ## d : \ - if (length == 0) goto finish; \ - *target = *seq ## a; \ - ++target; \ - --length; \ - ++seq ## a; \ - if (seq ## a c0 seq ## b) goto s ## a ## b ## c ## d; \ - if (seq ## a c1 seq ## c) goto s ## b ## a ## c ## d; \ - if (seq ## a c2 seq ## d) goto s ## b ## c ## a ## d; \ +#define STXXL_MERGE4CASE(a, b, c, d, c0, c1, c2) \ + s ## a ## b ## c ## d : \ + if (length == 0) goto finish; \ + *target = *seq ## a; \ + ++target; \ + --length; \ + ++seq ## a; \ + if (seq ## a c0 seq ## b) goto s ## a ## b ## c ## d; \ + if (seq ## a c1 seq ## c) goto s ## b ## a ## c ## d; \ + if (seq ## a c2 seq ## d) goto s ## b ## c ## a ## d; \ goto s ## b ## c ## d ## a; STXXL_MERGE4CASE(0, 1, 2, 3, <=, <=, <=); diff --git a/include/stxxl/bits/stream/sort_stream.h b/include/stxxl/bits/stream/sort_stream.h index b57bd47b8..062ea871d 100644 --- a/include/stxxl/bits/stream/sort_stream.h +++ b/include/stxxl/bits/stream/sort_stream.h @@ -412,11 +412,11 @@ template < class AllocStr > class runs_creator< - use_push, - CompareType, - BlockSize, - AllocStr - >: private noncopyable + use_push, + CompareType, + BlockSize, + AllocStr + >: private noncopyable { public: typedef CompareType cmp_type; @@ -720,11 +720,11 @@ template < class AllocStr > class runs_creator< - from_sorted_sequences, - CompareType, - BlockSize, - AllocStr - >: private noncopyable + from_sorted_sequences, + CompareType, + BlockSize, + AllocStr + >: private noncopyable { public: typedef ValueType value_type; diff --git a/lib/io/request_queue_impl_worker.cpp b/lib/io/request_queue_impl_worker.cpp index 0ae28144c..6566e68fa 100644 --- a/lib/io/request_queue_impl_worker.cpp +++ b/lib/io/request_queue_impl_worker.cpp @@ -32,7 +32,7 @@ STXXL_BEGIN_NAMESPACE -void request_queue_impl_worker::start_thread(void* (* worker)(void*), void* arg, thread_type& t, state& s) +void request_queue_impl_worker::start_thread(void* (*worker)(void*), void* arg, thread_type& t, state& s) { assert(s() == NOT_RUNNING); #if STXXL_STD_THREADS diff --git a/lib/io/ufs_file_base.cpp b/lib/io/ufs_file_base.cpp index e7993f6a7..18d661f7a 100644 --- a/lib/io/ufs_file_base.cpp +++ b/lib/io/ufs_file_base.cpp @@ -226,7 +226,7 @@ void ufs_file_base::_set_size(offset_type newsize) if (!(m_mode & RDONLY) && !m_is_device) { #if STXXL_WINDOWS || defined(__MINGW32__) - HANDLE hfile = (HANDLE) ::_get_osfhandle(file_des); + HANDLE hfile = (HANDLE)::_get_osfhandle(file_des); STXXL_THROW_ERRNO_NE_0((hfile == INVALID_HANDLE_VALUE), io_error, "_get_osfhandle() path=" << filename << " fd=" << file_des); diff --git a/lib/io/wfs_file_base.cpp b/lib/io/wfs_file_base.cpp index 4a0c5924f..2fe983573 100644 --- a/lib/io/wfs_file_base.cpp +++ b/lib/io/wfs_file_base.cpp @@ -88,7 +88,7 @@ static HANDLE open_file_impl(const std::string& filename, int mode) } HANDLE file_des = ::CreateFileA(filename.c_str(), dwDesiredAccess, dwShareMode, NULL, - dwCreationDisposition, dwFlagsAndAttributes, NULL); + dwCreationDisposition, dwFlagsAndAttributes, NULL); if (file_des != INVALID_HANDLE_VALUE) return file_des; @@ -101,7 +101,7 @@ static HANDLE open_file_impl(const std::string& filename, int mode) dwFlagsAndAttributes &= ~FILE_FLAG_NO_BUFFERING; HANDLE file_des = ::CreateFileA(filename.c_str(), dwDesiredAccess, dwShareMode, NULL, - dwCreationDisposition, dwFlagsAndAttributes, NULL); + dwCreationDisposition, dwFlagsAndAttributes, NULL); if (file_des != INVALID_HANDLE_VALUE) return file_des; diff --git a/lib/utils/malloc_count.cpp b/lib/utils/malloc_count.cpp index 473834f70..51ba44635 100644 --- a/lib/utils/malloc_count.cpp +++ b/lib/utils/malloc_count.cpp @@ -143,7 +143,7 @@ extern void * malloc(size_t size) throw () if (real_malloc) { /* call read malloc procedure in libc */ - ret = (* real_malloc)(alignment + size); + ret = (*real_malloc)(alignment + size); inc_count(size); if (log_operations && size >= log_operations_threshold) { @@ -217,7 +217,7 @@ extern void free(void* ptr) throw () ptr, (long long)size, curr); } - (* real_free)(ptr); + (*real_free)(ptr); } /* exported calloc() symbol that overrides loading from libc, implemented using @@ -291,7 +291,7 @@ extern void * realloc(void* ptr, size_t size) throw () dec_count(oldsize); inc_count(size); - newptr = (* real_realloc)(ptr, alignment + size); + newptr = (*real_realloc)(ptr, alignment + size); if (log_operations && size >= log_operations_threshold) { diff --git a/misc/uncrustify.cfg b/misc/uncrustify.cfg index 7f6398a31..25d65233a 100644 --- a/misc/uncrustify.cfg +++ b/misc/uncrustify.cfg @@ -1,37 +1,37 @@ -# Uncrustify 0.60 +# Uncrustify 0.61 # # General options # # The type of line endings -newlines = auto # auto/lf/crlf/cr +newlines = auto # auto/lf/crlf/cr # The original size of tabs in the input -input_tab_size = 8 # number +input_tab_size = 8 # number # The size of tabs in the output (only used if align_with_tabs=true) -output_tab_size = 8 # number +output_tab_size = 8 # number # The ASCII value of the string escape char, usually 92 (\) or 94 (^). (Pawn) -string_escape_char = 92 # number +string_escape_char = 92 # number # Alternate string escape char for Pawn. Only works right before the quote char. -string_escape_char2 = 0 # number +string_escape_char2 = 0 # number # Allow interpreting '>=' and '>>=' as part of a template in 'void f(list>=val);'. # If true (default), 'assert(x<0 && y>=3)' will be broken. # Improvements to template detection may make this option obsolete. -tok_split_gte = true # false/true +tok_split_gte = true # false/true # Control what to do with the UTF-8 BOM (recommend 'remove') -utf8_bom = ignore # ignore/add/remove/force +utf8_bom = ignore # ignore/add/remove/force # If the file contains bytes with values between 128 and 255, but is not UTF-8, then output as UTF-8 -utf8_byte = false # false/true +utf8_byte = false # false/true # Force the output encoding to UTF-8 -utf8_force = false # false/true +utf8_force = false # false/true # # Indenting @@ -39,1505 +39,1615 @@ utf8_force = false # false/true # The number of columns to indent per level. # Usually 2, 3, 4, or 8. -indent_columns = 4 # number +indent_columns = 4 # number # The continuation indent. If non-zero, this overrides the indent of '(' and '=' continuation indents. # For FreeBSD, this is set to 4. Negative value is absolute and not increased for each ( level -indent_continue = 0 # number +indent_continue = 0 # number # How to use tabs when indenting code # 0=spaces only # 1=indent with tabs to brace level, align with spaces # 2=indent and align with tabs, using spaces when not on a tabstop -indent_with_tabs = 0 # number +indent_with_tabs = 0 # number # Comments that are not a brace level are indented with tabs on a tabstop. # Requires indent_with_tabs=2. If false, will use spaces. -indent_cmt_with_tabs = false # false/true +indent_cmt_with_tabs = false # false/true # Whether to indent strings broken by '\' so that they line up -indent_align_string = false # false/true +indent_align_string = false # false/true # The number of spaces to indent multi-line XML strings. # Requires indent_align_string=True -indent_xml_string = 0 # number +indent_xml_string = 0 # number # Spaces to indent '{' from level -indent_brace = 0 # number +indent_brace = 0 # number # Whether braces are indented to the body level -indent_braces = false # false/true +indent_braces = false # false/true # Disabled indenting function braces if indent_braces is true -indent_braces_no_func = false # false/true +indent_braces_no_func = false # false/true # Disabled indenting class braces if indent_braces is true -indent_braces_no_class = false # false/true +indent_braces_no_class = false # false/true # Disabled indenting struct braces if indent_braces is true -indent_braces_no_struct = false # false/true +indent_braces_no_struct = false # false/true # Indent based on the size of the brace parent, i.e. 'if' => 3 spaces, 'for' => 4 spaces, etc. -indent_brace_parent = false # false/true +indent_brace_parent = false # false/true + +# Indent based on the paren open instead of the brace open in '({\n', default is to indent by brace. +indent_paren_open_brace = false # false/true # Whether the 'namespace' body is indented -indent_namespace = false # false/true +indent_namespace = false # false/true + +# Only indent one namespace and no sub-namepaces. +# Requires indent_namespace=true. +indent_namespace_single_indent = false # false/true # The number of spaces to indent a namespace block -indent_namespace_level = 0 # number +indent_namespace_level = 0 # number # If the body of the namespace is longer than this number, it won't be indented. # Requires indent_namespace=true. Default=0 (no limit) -indent_namespace_limit = 0 # number +indent_namespace_limit = 0 # number # Whether the 'extern "C"' body is indented -indent_extern = false # false/true +indent_extern = false # false/true # Whether the 'class' body is indented -indent_class = true # false/true +indent_class = true # false/true + +# Whether to indent the stuff after a leading base class colon +indent_class_colon = true # false/true -# Whether to indent the stuff after a leading class colon -indent_class_colon = true # false/true +# Whether to indent the stuff after a leading class initializer colon +indent_constr_colon = true # false/true # Virtual indent from the ':' for member initializers. Default is 2 -indent_ctor_init_leading = 2 # number +indent_ctor_init_leading = 2 # number # Additional indenting for constructor initializer list -indent_ctor_init = 0 # number +indent_ctor_init = 0 # number # False=treat 'else\nif' as 'else if' for indenting purposes # True=indent the 'if' one level -indent_else_if = false # false/true +indent_else_if = false # false/true # Amount to indent variable declarations after a open brace. neg=relative, pos=absolute -indent_var_def_blk = 0 # number +indent_var_def_blk = 0 # number # Indent continued variable declarations instead of aligning. -indent_var_def_cont = true # false/true +indent_var_def_cont = true # false/true # True: force indentation of function definition to start in column 1 # False: use the default behavior -indent_func_def_force_col1 = false # false/true +indent_func_def_force_col1 = false # false/true # True: indent continued function call parameters one indent level # False: align parameters under the open paren -indent_func_call_param = false # false/true +indent_func_call_param = false # false/true # Same as indent_func_call_param, but for function defs -indent_func_def_param = false # false/true +indent_func_def_param = false # false/true # Same as indent_func_call_param, but for function protos -indent_func_proto_param = false # false/true +indent_func_proto_param = false # false/true # Same as indent_func_call_param, but for class declarations -indent_func_class_param = false # false/true +indent_func_class_param = false # false/true # Same as indent_func_call_param, but for class variable constructors -indent_func_ctor_var_param = false # false/true +indent_func_ctor_var_param = false # false/true # Same as indent_func_call_param, but for templates -indent_template_param = false # false/true +indent_template_param = false # false/true # Double the indent for indent_func_xxx_param options -indent_func_param_double = false # false/true +indent_func_param_double = false # false/true # Indentation column for standalone 'const' function decl/proto qualifier -indent_func_const = 0 # number +indent_func_const = 0 # number # Indentation column for standalone 'throw' function decl/proto qualifier -indent_func_throw = 0 # number +indent_func_throw = 0 # number # The number of spaces to indent a continued '->' or '.' # Usually set to 0, 1, or indent_columns. -indent_member = 0 # number +indent_member = 0 # number # Spaces to indent single line ('//') comments on lines before code -indent_sing_line_comments = 0 # number +indent_sing_line_comments = 0 # number # If set, will indent trailing single line ('//') comments relative # to the code instead of trying to keep the same absolute column -indent_relative_single_line_comments = false # false/true +indent_relative_single_line_comments = false # false/true # Spaces to indent 'case' from 'switch' # Usually 0 or indent_columns. -indent_switch_case = 0 # number +indent_switch_case = 0 # number # Spaces to shift the 'case' line, without affecting any other lines # Usually 0. -indent_case_shift = 0 # number +indent_case_shift = 0 # number # Spaces to indent '{' from 'case'. # By default, the brace will appear under the 'c' in case. # Usually set to 0 or indent_columns. -indent_case_brace = 0 # number +indent_case_brace = 0 # number # Whether to indent comments found in first column -indent_col1_comment = false # false/true +indent_col1_comment = false # false/true # How to indent goto labels # >0 : absolute column where 1 is the leftmost column # <=0 : subtract from brace indent -indent_label = 1 # number +indent_label = 1 # number # Same as indent_label, but for access specifiers that are followed by a colon -indent_access_spec = -4 # number +indent_access_spec = -4 # number # Indent the code after an access specifier by one level. # If set, this option forces 'indent_access_spec=0' -indent_access_spec_body = false # false/true +indent_access_spec_body = false # false/true # If an open paren is followed by a newline, indent the next line so that it lines up after the open paren (not recommended) -indent_paren_nl = false # false/true +indent_paren_nl = false # false/true # Controls the indent of a close paren after a newline. # 0: Indent to body level # 1: Align under the open paren # 2: Indent to the brace level -indent_paren_close = 0 # number +indent_paren_close = 0 # number # Controls the indent of a comma when inside a paren.If TRUE, aligns under the open paren -indent_comma_paren = false # false/true +indent_comma_paren = false # false/true # Controls the indent of a BOOL operator when inside a paren.If TRUE, aligns under the open paren -indent_bool_paren = false # false/true +indent_bool_paren = false # false/true # If 'indent_bool_paren' is true, controls the indent of the first expression. If TRUE, aligns the first expression to the following ones -indent_first_bool_expr = false # false/true +indent_first_bool_expr = false # false/true # If an open square is followed by a newline, indent the next line so that it lines up after the open square (not recommended) -indent_square_nl = false # false/true +indent_square_nl = false # false/true # Don't change the relative indent of ESQL/C 'EXEC SQL' bodies -indent_preserve_sql = false # false/true +indent_preserve_sql = false # false/true # Align continued statements at the '='. Default=True # If FALSE or the '=' is followed by a newline, the next line is indent one tab. -indent_align_assign = true # false/true +indent_align_assign = true # false/true # Indent OC blocks at brace level instead of usual rules. -indent_oc_block = false # false/true +indent_oc_block = false # false/true # Indent OC blocks in a message relative to the parameter name. # 0=use indent_oc_block rules, 1+=spaces to indent -indent_oc_block_msg = 0 # number +indent_oc_block_msg = 0 # number # Minimum indent for subsequent parameters -indent_oc_msg_colon = 0 # number +indent_oc_msg_colon = 0 # number + +# If true, prioritize aligning with initial colon (and stripping spaces from lines, if necessary). +# Default is true. +indent_oc_msg_prioritize_first_colon = true # false/true + +# If indent_oc_block_msg and this option are on, blocks will be indented the way that Xcode does by default (from keyword if the parameter is on its own line; otherwise, from the previous indentation level). +indent_oc_block_msg_xcode_style = false # false/true + +# If indent_oc_block_msg and this option are on, blocks will be indented from where the brace is relative to a msg keyword. +indent_oc_block_msg_from_keyword = false # false/true + +# If indent_oc_block_msg and this option are on, blocks will be indented from where the brace is relative to a msg colon. +indent_oc_block_msg_from_colon = false # false/true + +# If indent_oc_block_msg and this option are on, blocks will be indented from where the block caret is. +indent_oc_block_msg_from_caret = false # false/true + +# If indent_oc_block_msg and this option are on, blocks will be indented from where the brace is. +indent_oc_block_msg_from_brace = false # false/true # # Spacing options # # Add or remove space around arithmetic operator '+', '-', '/', '*', etc -sp_arith = force # ignore/add/remove/force +sp_arith = force # ignore/add/remove/force # Add or remove space around assignment operator '=', '+=', etc -sp_assign = force # ignore/add/remove/force +sp_assign = force # ignore/add/remove/force # Add or remove space around '=' in C++11 lambda capture specifications. Overrides sp_assign -sp_cpp_lambda_assign = ignore # ignore/add/remove/force +sp_cpp_lambda_assign = ignore # ignore/add/remove/force # Add or remove space after the capture specification in C++11 lambda. -sp_cpp_lambda_paren = ignore # ignore/add/remove/force +sp_cpp_lambda_paren = ignore # ignore/add/remove/force # Add or remove space around assignment operator '=' in a prototype -sp_assign_default = force # ignore/add/remove/force +sp_assign_default = force # ignore/add/remove/force # Add or remove space before assignment operator '=', '+=', etc. Overrides sp_assign. -sp_before_assign = force # ignore/add/remove/force +sp_before_assign = force # ignore/add/remove/force # Add or remove space after assignment operator '=', '+=', etc. Overrides sp_assign. -sp_after_assign = force # ignore/add/remove/force +sp_after_assign = force # ignore/add/remove/force + +# Add or remove space in 'NS_ENUM (' +sp_enum_paren = ignore # ignore/add/remove/force # Add or remove space around assignment '=' in enum -sp_enum_assign = force # ignore/add/remove/force +sp_enum_assign = force # ignore/add/remove/force # Add or remove space before assignment '=' in enum. Overrides sp_enum_assign. -sp_enum_before_assign = force # ignore/add/remove/force +sp_enum_before_assign = force # ignore/add/remove/force # Add or remove space after assignment '=' in enum. Overrides sp_enum_assign. -sp_enum_after_assign = force # ignore/add/remove/force +sp_enum_after_assign = force # ignore/add/remove/force # Add or remove space around preprocessor '##' concatenation operator. Default=Add -sp_pp_concat = force # ignore/add/remove/force +sp_pp_concat = force # ignore/add/remove/force # Add or remove space after preprocessor '#' stringify operator. Also affects the '#@' charizing operator. -sp_pp_stringify = ignore # ignore/add/remove/force +sp_pp_stringify = ignore # ignore/add/remove/force # Add or remove space before preprocessor '#' stringify operator as in '#define x(y) L#y'. -sp_before_pp_stringify = ignore # ignore/add/remove/force +sp_before_pp_stringify = ignore # ignore/add/remove/force # Add or remove space around boolean operators '&&' and '||' -sp_bool = force # ignore/add/remove/force +sp_bool = force # ignore/add/remove/force # Add or remove space around compare operator '<', '>', '==', etc -sp_compare = force # ignore/add/remove/force +sp_compare = force # ignore/add/remove/force # Add or remove space inside '(' and ')' -sp_inside_paren = remove # ignore/add/remove/force +sp_inside_paren = remove # ignore/add/remove/force + +# Add or remove space between nested parens: '((' vs ') )' +sp_paren_paren = remove # ignore/add/remove/force -# Add or remove space between nested parens -sp_paren_paren = remove # ignore/add/remove/force +# Add or remove space between back-to-back parens: ')(' vs ') (' +sp_cparen_oparen = ignore # ignore/add/remove/force # Whether to balance spaces inside nested parens -sp_balance_nested_parens = false # false/true +sp_balance_nested_parens = false # false/true # Add or remove space between ')' and '{' -sp_paren_brace = force # ignore/add/remove/force +sp_paren_brace = force # ignore/add/remove/force # Add or remove space before pointer star '*' -sp_before_ptr_star = remove # ignore/add/remove/force +sp_before_ptr_star = remove # ignore/add/remove/force # Add or remove space before pointer star '*' that isn't followed by a variable name # If set to 'ignore', sp_before_ptr_star is used instead. -sp_before_unnamed_ptr_star = remove # ignore/add/remove/force +sp_before_unnamed_ptr_star = remove # ignore/add/remove/force # Add or remove space between pointer stars '*' -sp_between_ptr_star = remove # ignore/add/remove/force +sp_between_ptr_star = remove # ignore/add/remove/force # Add or remove space after pointer star '*', if followed by a word. -sp_after_ptr_star = force # ignore/add/remove/force +sp_after_ptr_star = force # ignore/add/remove/force + +# Add or remove space after pointer star '*', if followed by a qualifier. +sp_after_ptr_star_qualifier = force # ignore/add/remove/force # Add or remove space after a pointer star '*', if followed by a func proto/def. -sp_after_ptr_star_func = force # ignore/add/remove/force +sp_after_ptr_star_func = force # ignore/add/remove/force # Add or remove space after a pointer star '*', if followed by an open paren (function types). -sp_ptr_star_paren = ignore # ignore/add/remove/force +sp_ptr_star_paren = ignore # ignore/add/remove/force # Add or remove space before a pointer star '*', if followed by a func proto/def. -sp_before_ptr_star_func = force # ignore/add/remove/force +sp_before_ptr_star_func = force # ignore/add/remove/force # Add or remove space before a reference sign '&' -sp_before_byref = remove # ignore/add/remove/force +sp_before_byref = remove # ignore/add/remove/force # Add or remove space before a reference sign '&' that isn't followed by a variable name # If set to 'ignore', sp_before_byref is used instead. -sp_before_unnamed_byref = remove # ignore/add/remove/force +sp_before_unnamed_byref = remove # ignore/add/remove/force # Add or remove space after reference sign '&', if followed by a word. -sp_after_byref = force # ignore/add/remove/force +sp_after_byref = force # ignore/add/remove/force # Add or remove space after a reference sign '&', if followed by a func proto/def. -sp_after_byref_func = force # ignore/add/remove/force +sp_after_byref_func = force # ignore/add/remove/force # Add or remove space before a reference sign '&', if followed by a func proto/def. -sp_before_byref_func = force # ignore/add/remove/force +sp_before_byref_func = force # ignore/add/remove/force # Add or remove space between type and word. Default=Force -sp_after_type = force # ignore/add/remove/force +sp_after_type = force # ignore/add/remove/force # Add or remove space before the paren in the D constructs 'template Foo(' and 'class Foo('. -sp_before_template_paren = ignore # ignore/add/remove/force +sp_before_template_paren = ignore # ignore/add/remove/force # Add or remove space in 'template <' vs 'template<'. # If set to ignore, sp_before_angle is used. -sp_template_angle = force # ignore/add/remove/force +sp_template_angle = force # ignore/add/remove/force # Add or remove space before '<>' -sp_before_angle = remove # ignore/add/remove/force +sp_before_angle = remove # ignore/add/remove/force # Add or remove space inside '<' and '>' -sp_inside_angle = remove # ignore/add/remove/force +sp_inside_angle = remove # ignore/add/remove/force # Add or remove space after '<>' -sp_after_angle = remove # ignore/add/remove/force +sp_after_angle = remove # ignore/add/remove/force # Add or remove space between '<>' and '(' as found in 'new List();' -sp_angle_paren = remove # ignore/add/remove/force +sp_angle_paren = remove # ignore/add/remove/force # Add or remove space between '<>' and a word as in 'List m;' -sp_angle_word = force # ignore/add/remove/force +sp_angle_word = force # ignore/add/remove/force # Add or remove space between '>' and '>' in '>>' (template stuff C++/C# only). Default=Add -sp_angle_shift = force # ignore/add/remove/force +sp_angle_shift = force # ignore/add/remove/force # Permit removal of the space between '>>' in 'foo >' (C++11 only). Default=False # sp_angle_shift cannot remove the space without this option. -sp_permit_cpp11_shift = false # false/true +sp_permit_cpp11_shift = false # false/true # Add or remove space before '(' of 'if', 'for', 'switch', and 'while' -sp_before_sparen = force # ignore/add/remove/force +sp_before_sparen = force # ignore/add/remove/force # Add or remove space inside if-condition '(' and ')' -sp_inside_sparen = remove # ignore/add/remove/force +sp_inside_sparen = remove # ignore/add/remove/force # Add or remove space before if-condition ')'. Overrides sp_inside_sparen. -sp_inside_sparen_close = ignore # ignore/add/remove/force +sp_inside_sparen_close = ignore # ignore/add/remove/force # Add or remove space before if-condition '('. Overrides sp_inside_sparen. -sp_inside_sparen_open = ignore # ignore/add/remove/force +sp_inside_sparen_open = ignore # ignore/add/remove/force # Add or remove space after ')' of 'if', 'for', 'switch', and 'while' -sp_after_sparen = force # ignore/add/remove/force +sp_after_sparen = force # ignore/add/remove/force # Add or remove space between ')' and '{' of 'if', 'for', 'switch', and 'while' -sp_sparen_brace = force # ignore/add/remove/force +sp_sparen_brace = force # ignore/add/remove/force # Add or remove space between 'invariant' and '(' in the D language. -sp_invariant_paren = ignore # ignore/add/remove/force +sp_invariant_paren = ignore # ignore/add/remove/force # Add or remove space after the ')' in 'invariant (C) c' in the D language. -sp_after_invariant_paren = ignore # ignore/add/remove/force +sp_after_invariant_paren = ignore # ignore/add/remove/force # Add or remove space before empty statement ';' on 'if', 'for' and 'while' -sp_special_semi = force # ignore/add/remove/force +sp_special_semi = force # ignore/add/remove/force # Add or remove space before ';'. Default=Remove -sp_before_semi = remove # ignore/add/remove/force +sp_before_semi = remove # ignore/add/remove/force # Add or remove space before ';' in non-empty 'for' statements -sp_before_semi_for = remove # ignore/add/remove/force +sp_before_semi_for = remove # ignore/add/remove/force # Add or remove space before a semicolon of an empty part of a for statement. -sp_before_semi_for_empty = force # ignore/add/remove/force +sp_before_semi_for_empty = force # ignore/add/remove/force # Add or remove space after ';', except when followed by a comment. Default=Add -sp_after_semi = add # ignore/add/remove/force +sp_after_semi = add # ignore/add/remove/force # Add or remove space after ';' in non-empty 'for' statements. Default=Force -sp_after_semi_for = force # ignore/add/remove/force +sp_after_semi_for = force # ignore/add/remove/force # Add or remove space after the final semicolon of an empty part of a for statement: for ( ; ; ). -sp_after_semi_for_empty = force # ignore/add/remove/force +sp_after_semi_for_empty = force # ignore/add/remove/force # Add or remove space before '[' (except '[]') -sp_before_square = remove # ignore/add/remove/force +sp_before_square = remove # ignore/add/remove/force # Add or remove space before '[]' -sp_before_squares = remove # ignore/add/remove/force +sp_before_squares = remove # ignore/add/remove/force # Add or remove space inside a non-empty '[' and ']' -sp_inside_square = remove # ignore/add/remove/force +sp_inside_square = remove # ignore/add/remove/force # Add or remove space after ',' -sp_after_comma = force # ignore/add/remove/force +sp_after_comma = force # ignore/add/remove/force # Add or remove space before ',' -sp_before_comma = remove # ignore/add/remove/force +sp_before_comma = remove # ignore/add/remove/force # Add or remove space between an open paren and comma: '(,' vs '( ,' -sp_paren_comma = force # ignore/add/remove/force +sp_paren_comma = force # ignore/add/remove/force # Add or remove space before the variadic '...' when preceded by a non-punctuator -sp_before_ellipsis = ignore # ignore/add/remove/force +sp_before_ellipsis = ignore # ignore/add/remove/force # Add or remove space after class ':' -sp_after_class_colon = force # ignore/add/remove/force +sp_after_class_colon = force # ignore/add/remove/force # Add or remove space before class ':' -sp_before_class_colon = force # ignore/add/remove/force +sp_before_class_colon = force # ignore/add/remove/force + +# Add or remove space after class constructor ':' +sp_after_constr_colon = ignore # ignore/add/remove/force + +# Add or remove space before class constructor ':' +sp_before_constr_colon = ignore # ignore/add/remove/force # Add or remove space before case ':'. Default=Remove -sp_before_case_colon = remove # ignore/add/remove/force +sp_before_case_colon = remove # ignore/add/remove/force # Add or remove space between 'operator' and operator sign -sp_after_operator = force # ignore/add/remove/force +sp_after_operator = force # ignore/add/remove/force # Add or remove space between the operator symbol and the open paren, as in 'operator ++(' -sp_after_operator_sym = force # ignore/add/remove/force +sp_after_operator_sym = force # ignore/add/remove/force # Add or remove space after C/D cast, i.e. 'cast(int)a' vs 'cast(int) a' or '(int)a' vs '(int) a' -sp_after_cast = remove # ignore/add/remove/force +sp_after_cast = remove # ignore/add/remove/force # Add or remove spaces inside cast parens -sp_inside_paren_cast = remove # ignore/add/remove/force +sp_inside_paren_cast = remove # ignore/add/remove/force # Add or remove space between the type and open paren in a C++ cast, i.e. 'int(exp)' vs 'int (exp)' -sp_cpp_cast_paren = remove # ignore/add/remove/force +sp_cpp_cast_paren = remove # ignore/add/remove/force # Add or remove space between 'sizeof' and '(' -sp_sizeof_paren = remove # ignore/add/remove/force +sp_sizeof_paren = remove # ignore/add/remove/force # Add or remove space after the tag keyword (Pawn) -sp_after_tag = ignore # ignore/add/remove/force +sp_after_tag = ignore # ignore/add/remove/force # Add or remove space inside enum '{' and '}' -sp_inside_braces_enum = force # ignore/add/remove/force +sp_inside_braces_enum = force # ignore/add/remove/force # Add or remove space inside struct/union '{' and '}' -sp_inside_braces_struct = force # ignore/add/remove/force +sp_inside_braces_struct = force # ignore/add/remove/force # Add or remove space inside '{' and '}' -sp_inside_braces = force # ignore/add/remove/force +sp_inside_braces = force # ignore/add/remove/force # Add or remove space inside '{}' -sp_inside_braces_empty = force # ignore/add/remove/force +sp_inside_braces_empty = force # ignore/add/remove/force # Add or remove space between return type and function name # A minimum of 1 is forced except for pointer return types. -sp_type_func = force # ignore/add/remove/force +sp_type_func = force # ignore/add/remove/force # Add or remove space between function name and '(' on function declaration -sp_func_proto_paren = remove # ignore/add/remove/force +sp_func_proto_paren = remove # ignore/add/remove/force # Add or remove space between function name and '(' on function definition -sp_func_def_paren = remove # ignore/add/remove/force +sp_func_def_paren = remove # ignore/add/remove/force # Add or remove space inside empty function '()' -sp_inside_fparens = remove # ignore/add/remove/force +sp_inside_fparens = remove # ignore/add/remove/force # Add or remove space inside function '(' and ')' -sp_inside_fparen = remove # ignore/add/remove/force +sp_inside_fparen = remove # ignore/add/remove/force # Add or remove space inside the first parens in the function type: 'void (*x)(...)' -sp_inside_tparen = ignore # ignore/add/remove/force +sp_inside_tparen = ignore # ignore/add/remove/force # Add or remove between the parens in the function type: 'void (*x)(...)' -sp_after_tparen_close = ignore # ignore/add/remove/force +sp_after_tparen_close = ignore # ignore/add/remove/force # Add or remove space between ']' and '(' when part of a function call. -sp_square_fparen = remove # ignore/add/remove/force +sp_square_fparen = remove # ignore/add/remove/force # Add or remove space between ')' and '{' of function -sp_fparen_brace = force # ignore/add/remove/force +sp_fparen_brace = force # ignore/add/remove/force + +# Java: Add or remove space between ')' and '{{' of double brace initializer. +sp_fparen_dbrace = ignore # ignore/add/remove/force # Add or remove space between function name and '(' on function calls -sp_func_call_paren = remove # ignore/add/remove/force +sp_func_call_paren = remove # ignore/add/remove/force # Add or remove space between function name and '()' on function calls without parameters. # If set to 'ignore' (the default), sp_func_call_paren is used. -sp_func_call_paren_empty = ignore # ignore/add/remove/force +sp_func_call_paren_empty = ignore # ignore/add/remove/force # Add or remove space between the user function name and '(' on function calls # You need to set a keyword to be a user function, like this: 'set func_call_user _' in the config file. -sp_func_call_user_paren = remove # ignore/add/remove/force +sp_func_call_user_paren = remove # ignore/add/remove/force # Add or remove space between a constructor/destructor and the open paren -sp_func_class_paren = remove # ignore/add/remove/force +sp_func_class_paren = remove # ignore/add/remove/force # Add or remove space between 'return' and '(' -sp_return_paren = force # ignore/add/remove/force +sp_return_paren = force # ignore/add/remove/force # Add or remove space between '__attribute__' and '(' -sp_attribute_paren = force # ignore/add/remove/force +sp_attribute_paren = force # ignore/add/remove/force # Add or remove space between 'defined' and '(' in '#if defined (FOO)' -sp_defined_paren = ignore # ignore/add/remove/force +sp_defined_paren = ignore # ignore/add/remove/force # Add or remove space between 'throw' and '(' in 'throw (something)' -sp_throw_paren = force # ignore/add/remove/force +sp_throw_paren = force # ignore/add/remove/force # Add or remove space between 'throw' and anything other than '(' as in '@throw [...];' -sp_after_throw = ignore # ignore/add/remove/force +sp_after_throw = ignore # ignore/add/remove/force # Add or remove space between 'catch' and '(' in 'catch (something) { }' # If set to ignore, sp_before_sparen is used. -sp_catch_paren = force # ignore/add/remove/force +sp_catch_paren = force # ignore/add/remove/force # Add or remove space between 'version' and '(' in 'version (something) { }' (D language) # If set to ignore, sp_before_sparen is used. -sp_version_paren = ignore # ignore/add/remove/force +sp_version_paren = ignore # ignore/add/remove/force # Add or remove space between 'scope' and '(' in 'scope (something) { }' (D language) # If set to ignore, sp_before_sparen is used. -sp_scope_paren = ignore # ignore/add/remove/force +sp_scope_paren = ignore # ignore/add/remove/force # Add or remove space between macro and value -sp_macro = ignore # ignore/add/remove/force +sp_macro = ignore # ignore/add/remove/force # Add or remove space between macro function ')' and value -sp_macro_func = ignore # ignore/add/remove/force +sp_macro_func = ignore # ignore/add/remove/force # Add or remove space between 'else' and '{' if on the same line -sp_else_brace = force # ignore/add/remove/force +sp_else_brace = force # ignore/add/remove/force # Add or remove space between '}' and 'else' if on the same line -sp_brace_else = force # ignore/add/remove/force +sp_brace_else = force # ignore/add/remove/force # Add or remove space between '}' and the name of a typedef on the same line -sp_brace_typedef = force # ignore/add/remove/force +sp_brace_typedef = force # ignore/add/remove/force # Add or remove space between 'catch' and '{' if on the same line -sp_catch_brace = force # ignore/add/remove/force +sp_catch_brace = force # ignore/add/remove/force # Add or remove space between '}' and 'catch' if on the same line -sp_brace_catch = force # ignore/add/remove/force +sp_brace_catch = force # ignore/add/remove/force # Add or remove space between 'finally' and '{' if on the same line -sp_finally_brace = force # ignore/add/remove/force +sp_finally_brace = force # ignore/add/remove/force # Add or remove space between '}' and 'finally' if on the same line -sp_brace_finally = force # ignore/add/remove/force +sp_brace_finally = force # ignore/add/remove/force # Add or remove space between 'try' and '{' if on the same line -sp_try_brace = force # ignore/add/remove/force +sp_try_brace = force # ignore/add/remove/force # Add or remove space between get/set and '{' if on the same line -sp_getset_brace = ignore # ignore/add/remove/force +sp_getset_brace = ignore # ignore/add/remove/force + +# Add or remove space between a variable and '{' for C++ uniform initialization +sp_word_brace = add # ignore/add/remove/force + +# Add or remove space between a variable and '{' for a namespace +sp_word_brace_ns = add # ignore/add/remove/force # Add or remove space before the '::' operator -sp_before_dc = remove # ignore/add/remove/force +sp_before_dc = remove # ignore/add/remove/force # Add or remove space after the '::' operator -sp_after_dc = remove # ignore/add/remove/force +sp_after_dc = remove # ignore/add/remove/force # Add or remove around the D named array initializer ':' operator -sp_d_array_colon = ignore # ignore/add/remove/force +sp_d_array_colon = ignore # ignore/add/remove/force # Add or remove space after the '!' (not) operator. Default=Remove -sp_not = ignore # ignore/add/remove/force +sp_not = ignore # ignore/add/remove/force # Add or remove space after the '~' (invert) operator. Default=Remove -sp_inv = remove # ignore/add/remove/force +sp_inv = remove # ignore/add/remove/force # Add or remove space after the '&' (address-of) operator. Default=Remove # This does not affect the spacing after a '&' that is part of a type. -sp_addr = remove # ignore/add/remove/force +sp_addr = remove # ignore/add/remove/force # Add or remove space around the '.' or '->' operators. Default=Remove -sp_member = remove # ignore/add/remove/force +sp_member = remove # ignore/add/remove/force # Add or remove space after the '*' (dereference) operator. Default=Remove # This does not affect the spacing after a '*' that is part of a type. -sp_deref = remove # ignore/add/remove/force +sp_deref = remove # ignore/add/remove/force # Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'. Default=Remove -sp_sign = remove # ignore/add/remove/force +sp_sign = remove # ignore/add/remove/force # Add or remove space before or after '++' and '--', as in '(--x)' or 'y++;'. Default=Remove -sp_incdec = remove # ignore/add/remove/force +sp_incdec = remove # ignore/add/remove/force # Add or remove space before a backslash-newline at the end of a line. Default=Add -sp_before_nl_cont = force # ignore/add/remove/force +sp_before_nl_cont = force # ignore/add/remove/force # Add or remove space after the scope '+' or '-', as in '-(void) foo;' or '+(int) bar;' -sp_after_oc_scope = ignore # ignore/add/remove/force +sp_after_oc_scope = ignore # ignore/add/remove/force # Add or remove space after the colon in message specs # '-(int) f:(int) x;' vs '-(int) f: (int) x;' -sp_after_oc_colon = ignore # ignore/add/remove/force +sp_after_oc_colon = ignore # ignore/add/remove/force # Add or remove space before the colon in message specs # '-(int) f: (int) x;' vs '-(int) f : (int) x;' -sp_before_oc_colon = ignore # ignore/add/remove/force +sp_before_oc_colon = ignore # ignore/add/remove/force # Add or remove space after the colon in immutable dictionary expression # 'NSDictionary *test = @{@"foo" :@"bar"};' -sp_after_oc_dict_colon = ignore # ignore/add/remove/force +sp_after_oc_dict_colon = ignore # ignore/add/remove/force # Add or remove space before the colon in immutable dictionary expression # 'NSDictionary *test = @{@"foo" :@"bar"};' -sp_before_oc_dict_colon = ignore # ignore/add/remove/force +sp_before_oc_dict_colon = ignore # ignore/add/remove/force # Add or remove space after the colon in message specs # '[object setValue:1];' vs '[object setValue: 1];' -sp_after_send_oc_colon = ignore # ignore/add/remove/force +sp_after_send_oc_colon = ignore # ignore/add/remove/force # Add or remove space before the colon in message specs # '[object setValue:1];' vs '[object setValue :1];' -sp_before_send_oc_colon = ignore # ignore/add/remove/force +sp_before_send_oc_colon = ignore # ignore/add/remove/force # Add or remove space after the (type) in message specs # '-(int)f: (int) x;' vs '-(int)f: (int)x;' -sp_after_oc_type = ignore # ignore/add/remove/force +sp_after_oc_type = ignore # ignore/add/remove/force # Add or remove space after the first (type) in message specs # '-(int) f:(int)x;' vs '-(int)f:(int)x;' -sp_after_oc_return_type = ignore # ignore/add/remove/force +sp_after_oc_return_type = ignore # ignore/add/remove/force # Add or remove space between '@selector' and '(' # '@selector(msgName)' vs '@selector (msgName)' # Also applies to @protocol() constructs -sp_after_oc_at_sel = ignore # ignore/add/remove/force +sp_after_oc_at_sel = ignore # ignore/add/remove/force # Add or remove space between '@selector(x)' and the following word # '@selector(foo) a:' vs '@selector(foo)a:' -sp_after_oc_at_sel_parens = ignore # ignore/add/remove/force +sp_after_oc_at_sel_parens = ignore # ignore/add/remove/force # Add or remove space inside '@selector' parens # '@selector(foo)' vs '@selector( foo )' # Also applies to @protocol() constructs -sp_inside_oc_at_sel_parens = ignore # ignore/add/remove/force +sp_inside_oc_at_sel_parens = ignore # ignore/add/remove/force # Add or remove space before a block pointer caret # '^int (int arg){...}' vs. ' ^int (int arg){...}' -sp_before_oc_block_caret = ignore # ignore/add/remove/force +sp_before_oc_block_caret = ignore # ignore/add/remove/force # Add or remove space after a block pointer caret # '^int (int arg){...}' vs. '^ int (int arg){...}' -sp_after_oc_block_caret = ignore # ignore/add/remove/force +sp_after_oc_block_caret = ignore # ignore/add/remove/force # Add or remove space between the receiver and selector in a message. # '[receiver selector ...]' -sp_after_oc_msg_receiver = ignore # ignore/add/remove/force +sp_after_oc_msg_receiver = ignore # ignore/add/remove/force # Add or remove space after @property. -sp_after_oc_property = ignore # ignore/add/remove/force +sp_after_oc_property = ignore # ignore/add/remove/force # Add or remove space around the ':' in 'b ? t : f' -sp_cond_colon = force # ignore/add/remove/force +sp_cond_colon = force # ignore/add/remove/force + +# Add or remove space before the ':' in 'b ? t : f'. Overrides sp_cond_colon. +sp_cond_colon_before = ignore # ignore/add/remove/force + +# Add or remove space after the ':' in 'b ? t : f'. Overrides sp_cond_colon. +sp_cond_colon_after = ignore # ignore/add/remove/force # Add or remove space around the '?' in 'b ? t : f' -sp_cond_question = force # ignore/add/remove/force +sp_cond_question = force # ignore/add/remove/force + +# Add or remove space before the '?' in 'b ? t : f'. Overrides sp_cond_question. +sp_cond_question_before = ignore # ignore/add/remove/force + +# Add or remove space after the '?' in 'b ? t : f'. Overrides sp_cond_question. +sp_cond_question_after = ignore # ignore/add/remove/force + +# In the abbreviated ternary form (a ?: b), add/remove space between ? and :.'. Overrides all other sp_cond_* options. +sp_cond_ternary_short = ignore # ignore/add/remove/force # Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make sense here. -sp_case_label = force # ignore/add/remove/force +sp_case_label = force # ignore/add/remove/force # Control the space around the D '..' operator. -sp_range = ignore # ignore/add/remove/force +sp_range = ignore # ignore/add/remove/force # Control the spacing after ':' in 'for (TYPE VAR : EXPR)' (Java) -sp_after_for_colon = ignore # ignore/add/remove/force +sp_after_for_colon = ignore # ignore/add/remove/force # Control the spacing before ':' in 'for (TYPE VAR : EXPR)' (Java) -sp_before_for_colon = ignore # ignore/add/remove/force +sp_before_for_colon = ignore # ignore/add/remove/force # Control the spacing in 'extern (C)' (D) -sp_extern_paren = ignore # ignore/add/remove/force +sp_extern_paren = ignore # ignore/add/remove/force # Control the space after the opening of a C++ comment '// A' vs '//A' -sp_cmt_cpp_start = ignore # ignore/add/remove/force +sp_cmt_cpp_start = ignore # ignore/add/remove/force # Controls the spaces between #else or #endif and a trailing comment -sp_endif_cmt = ignore # ignore/add/remove/force +sp_endif_cmt = ignore # ignore/add/remove/force # Controls the spaces after 'new', 'delete', and 'delete[]' -sp_after_new = add # ignore/add/remove/force +sp_after_new = add # ignore/add/remove/force # Controls the spaces before a trailing or embedded comment -sp_before_tr_emb_cmt = ignore # ignore/add/remove/force +sp_before_tr_emb_cmt = ignore # ignore/add/remove/force # Number of spaces before a trailing or embedded comment -sp_num_before_tr_emb_cmt = 0 # number +sp_num_before_tr_emb_cmt = 0 # number # Control space between a Java annotation and the open paren. -sp_annotation_paren = ignore # ignore/add/remove/force +sp_annotation_paren = ignore # ignore/add/remove/force # # Code alignment (not left column spaces/tabs) # # Whether to keep non-indenting tabs -align_keep_tabs = false # false/true +align_keep_tabs = false # false/true # Whether to use tabs for aligning -align_with_tabs = false # false/true +align_with_tabs = false # false/true # Whether to bump out to the next tab when aligning -align_on_tabstop = false # false/true +align_on_tabstop = false # false/true # Whether to left-align numbers -align_number_left = false # false/true +align_number_left = false # false/true + +# Whether to keep whitespace not required for alignment. +align_keep_extra_space = false # false/true # Align variable definitions in prototypes and functions -align_func_params = false # false/true +align_func_params = false # false/true # Align parameters in single-line functions that have the same name. # The function names must already be aligned with each other. -align_same_func_call_params = false # false/true +align_same_func_call_params = false # false/true # The span for aligning variable definitions (0=don't align) -align_var_def_span = 0 # number +align_var_def_span = 0 # number # How to align the star in variable definitions. # 0=Part of the type 'void * foo;' # 1=Part of the variable 'void *foo;' # 2=Dangling 'void *foo;' -align_var_def_star_style = 1 # number +align_var_def_star_style = 1 # number # How to align the '&' in variable definitions. # 0=Part of the type # 1=Part of the variable # 2=Dangling -align_var_def_amp_style = 0 # number +align_var_def_amp_style = 0 # number # The threshold for aligning variable definitions (0=no limit) -align_var_def_thresh = 0 # number +align_var_def_thresh = 0 # number # The gap for aligning variable definitions -align_var_def_gap = 0 # number +align_var_def_gap = 0 # number # Whether to align the colon in struct bit fields -align_var_def_colon = false # false/true +align_var_def_colon = false # false/true # Whether to align any attribute after the variable name -align_var_def_attribute = false # false/true +align_var_def_attribute = false # false/true # Whether to align inline struct/enum/union variable definitions -align_var_def_inline = false # false/true +align_var_def_inline = false # false/true # The span for aligning on '=' in assignments (0=don't align) -align_assign_span = 0 # number +align_assign_span = 0 # number # The threshold for aligning on '=' in assignments (0=no limit) -align_assign_thresh = 0 # number +align_assign_thresh = 0 # number # The span for aligning on '=' in enums (0=don't align) -align_enum_equ_span = 0 # number +align_enum_equ_span = 0 # number # The threshold for aligning on '=' in enums (0=no limit) -align_enum_equ_thresh = 0 # number +align_enum_equ_thresh = 0 # number # The span for aligning struct/union (0=don't align) -align_var_struct_span = 0 # number +align_var_struct_span = 0 # number # The threshold for aligning struct/union member definitions (0=no limit) -align_var_struct_thresh = 0 # number +align_var_struct_thresh = 0 # number # The gap for aligning struct/union member definitions -align_var_struct_gap = 0 # number +align_var_struct_gap = 0 # number # The span for aligning struct initializer values (0=don't align) -align_struct_init_span = 0 # number +align_struct_init_span = 0 # number # The minimum space between the type and the synonym of a typedef -align_typedef_gap = 0 # number +align_typedef_gap = 0 # number # The span for aligning single-line typedefs (0=don't align) -align_typedef_span = 0 # number +align_typedef_span = 0 # number # How to align typedef'd functions with other typedefs # 0: Don't mix them at all # 1: align the open paren with the types # 2: align the function type name with the other type names -align_typedef_func = 0 # number +align_typedef_func = 0 # number # Controls the positioning of the '*' in typedefs. Just try it. # 0: Align on typedef type, ignore '*' # 1: The '*' is part of type name: typedef int *pint; # 2: The '*' is part of the type, but dangling: typedef int *pint; -align_typedef_star_style = 0 # number +align_typedef_star_style = 0 # number # Controls the positioning of the '&' in typedefs. Just try it. # 0: Align on typedef type, ignore '&' # 1: The '&' is part of type name: typedef int &pint; # 2: The '&' is part of the type, but dangling: typedef int &pint; -align_typedef_amp_style = 0 # number +align_typedef_amp_style = 0 # number # The span for aligning comments that end lines (0=don't align) -align_right_cmt_span = 5 # number +align_right_cmt_span = 5 # number # If aligning comments, mix with comments after '}' and #endif with less than 3 spaces before the comment -align_right_cmt_mix = false # false/true +align_right_cmt_mix = false # false/true # If a trailing comment is more than this number of columns away from the text it follows, # it will qualify for being aligned. This has to be > 0 to do anything. -align_right_cmt_gap = 0 # number +align_right_cmt_gap = 0 # number # Align trailing comment at or beyond column N; 'pulls in' comments as a bonus side effect (0=ignore) -align_right_cmt_at_col = 0 # number +align_right_cmt_at_col = 0 # number # The span for aligning function prototypes (0=don't align) -align_func_proto_span = 0 # number +align_func_proto_span = 0 # number # Minimum gap between the return type and the function name. -align_func_proto_gap = 0 # number +align_func_proto_gap = 0 # number # Align function protos on the 'operator' keyword instead of what follows -align_on_operator = false # false/true +align_on_operator = false # false/true # Whether to mix aligning prototype and variable declarations. # If true, align_var_def_XXX options are used instead of align_func_proto_XXX options. -align_mix_var_proto = false # false/true +align_mix_var_proto = false # false/true # Align single-line functions with function prototypes, uses align_func_proto_span -align_single_line_func = false # false/true +align_single_line_func = false # false/true # Aligning the open brace of single-line functions. # Requires align_single_line_func=true, uses align_func_proto_span -align_single_line_brace = false # false/true +align_single_line_brace = false # false/true # Gap for align_single_line_brace. -align_single_line_brace_gap = 0 # number +align_single_line_brace_gap = 0 # number # The span for aligning ObjC msg spec (0=don't align) -align_oc_msg_spec_span = 0 # number +align_oc_msg_spec_span = 0 # number # Whether to align macros wrapped with a backslash and a newline. # This will not work right if the macro contains a multi-line comment. -align_nl_cont = true # false/true +align_nl_cont = true # false/true # # Align macro functions and variables together -align_pp_define_together = false # false/true +align_pp_define_together = false # false/true # The minimum space between label and value of a preprocessor define -align_pp_define_gap = 0 # number +align_pp_define_gap = 0 # number -# The span for aligning on '#define' bodies (0=don't align) -align_pp_define_span = 0 # number +# The span for aligning on '#define' bodies (0=don't align, other=number of lines including comments between blocks) +align_pp_define_span = 0 # number # Align lines that start with '<<' with previous '<<'. Default=true -align_left_shift = true # false/true +align_left_shift = true # false/true # Span for aligning parameters in an Obj-C message call on the ':' (0=don't align) -align_oc_msg_colon_span = 0 # number +align_oc_msg_colon_span = 0 # number # If true, always align with the first parameter, even if it is too short. -align_oc_msg_colon_first = false # false/true +align_oc_msg_colon_first = false # false/true # Aligning parameters in an Obj-C '+' or '-' declaration on the ':' -align_oc_decl_colon = false # false/true +align_oc_decl_colon = false # false/true # # Newline adding and removing options # # Whether to collapse empty blocks between '{' and '}' -nl_collapse_empty_body = true # false/true +nl_collapse_empty_body = true # false/true # Don't split one-line braced assignments - 'foo_t f = { 1, 2 };' -nl_assign_leave_one_liners = true # false/true +nl_assign_leave_one_liners = true # false/true # Don't split one-line braced statements inside a class xx { } body -nl_class_leave_one_liners = true # false/true +nl_class_leave_one_liners = true # false/true # Don't split one-line enums: 'enum foo { BAR = 15 };' -nl_enum_leave_one_liners = true # false/true +nl_enum_leave_one_liners = true # false/true # Don't split one-line get or set functions -nl_getset_leave_one_liners = true # false/true +nl_getset_leave_one_liners = true # false/true # Don't split one-line function definitions - 'int foo() { return 0; }' -nl_func_leave_one_liners = false # false/true +nl_func_leave_one_liners = false # false/true + +# Don't split one-line C++11 lambdas - '[]() { return 0; }' +nl_cpp_lambda_leave_one_liners = false # false/true # Don't split one-line if/else statements - 'if(a) b++;' -nl_if_leave_one_liners = false # false/true +nl_if_leave_one_liners = false # false/true # Don't split one-line OC messages -nl_oc_msg_leave_one_liner = false # false/true +nl_oc_msg_leave_one_liner = false # false/true # Add or remove newlines at the start of the file -nl_start_of_file = remove # ignore/add/remove/force +nl_start_of_file = remove # ignore/add/remove/force # The number of newlines at the start of the file (only used if nl_start_of_file is 'add' or 'force' -nl_start_of_file_min = 0 # number +nl_start_of_file_min = 0 # number # Add or remove newline at the end of the file -nl_end_of_file = force # ignore/add/remove/force +nl_end_of_file = force # ignore/add/remove/force # The number of newlines at the end of the file (only used if nl_end_of_file is 'add' or 'force') -nl_end_of_file_min = 1 # number +nl_end_of_file_min = 1 # number # Add or remove newline between '=' and '{' -nl_assign_brace = ignore # ignore/add/remove/force +nl_assign_brace = ignore # ignore/add/remove/force # Add or remove newline between '=' and '[' (D only) -nl_assign_square = ignore # ignore/add/remove/force +nl_assign_square = ignore # ignore/add/remove/force # Add or remove newline after '= [' (D only). Will also affect the newline before the ']' -nl_after_square_assign = ignore # ignore/add/remove/force +nl_after_square_assign = ignore # ignore/add/remove/force # The number of blank lines after a block of variable definitions at the top of a function body # 0 = No change (default) -nl_func_var_def_blk = 0 # number +nl_func_var_def_blk = 0 # number # The number of newlines before a block of typedefs # 0 = No change (default) -nl_typedef_blk_start = 0 # number +nl_typedef_blk_start = 0 # number # The number of newlines after a block of typedefs # 0 = No change (default) -nl_typedef_blk_end = 0 # number +nl_typedef_blk_end = 0 # number # The maximum consecutive newlines within a block of typedefs # 0 = No change (default) -nl_typedef_blk_in = 0 # number +nl_typedef_blk_in = 0 # number # The number of newlines before a block of variable definitions not at the top of a function body # 0 = No change (default) -nl_var_def_blk_start = 0 # number +nl_var_def_blk_start = 0 # number # The number of newlines after a block of variable definitions not at the top of a function body # 0 = No change (default) -nl_var_def_blk_end = 0 # number +nl_var_def_blk_end = 0 # number # The maximum consecutive newlines within a block of variable definitions # 0 = No change (default) -nl_var_def_blk_in = 0 # number +nl_var_def_blk_in = 0 # number # Add or remove newline between a function call's ')' and '{', as in: # list_for_each(item, &list) { } -nl_fcall_brace = ignore # ignore/add/remove/force +nl_fcall_brace = ignore # ignore/add/remove/force # Add or remove newline between 'enum' and '{' -nl_enum_brace = ignore # ignore/add/remove/force +nl_enum_brace = ignore # ignore/add/remove/force # Add or remove newline between 'struct and '{' -nl_struct_brace = ignore # ignore/add/remove/force +nl_struct_brace = ignore # ignore/add/remove/force # Add or remove newline between 'union' and '{' -nl_union_brace = ignore # ignore/add/remove/force +nl_union_brace = ignore # ignore/add/remove/force # Add or remove newline between 'if' and '{' -nl_if_brace = ignore # ignore/add/remove/force +nl_if_brace = ignore # ignore/add/remove/force # Add or remove newline between '}' and 'else' -nl_brace_else = force # ignore/add/remove/force +nl_brace_else = force # ignore/add/remove/force # Add or remove newline between 'else if' and '{' # If set to ignore, nl_if_brace is used instead -nl_elseif_brace = ignore # ignore/add/remove/force +nl_elseif_brace = ignore # ignore/add/remove/force # Add or remove newline between 'else' and '{' -nl_else_brace = ignore # ignore/add/remove/force +nl_else_brace = ignore # ignore/add/remove/force # Add or remove newline between 'else' and 'if' -nl_else_if = remove # ignore/add/remove/force +nl_else_if = remove # ignore/add/remove/force # Add or remove newline between '}' and 'finally' -nl_brace_finally = ignore # ignore/add/remove/force +nl_brace_finally = ignore # ignore/add/remove/force # Add or remove newline between 'finally' and '{' -nl_finally_brace = ignore # ignore/add/remove/force +nl_finally_brace = ignore # ignore/add/remove/force # Add or remove newline between 'try' and '{' -nl_try_brace = ignore # ignore/add/remove/force +nl_try_brace = ignore # ignore/add/remove/force # Add or remove newline between get/set and '{' -nl_getset_brace = ignore # ignore/add/remove/force +nl_getset_brace = ignore # ignore/add/remove/force # Add or remove newline between 'for' and '{' -nl_for_brace = ignore # ignore/add/remove/force +nl_for_brace = ignore # ignore/add/remove/force # Add or remove newline between 'catch' and '{' -nl_catch_brace = ignore # ignore/add/remove/force +nl_catch_brace = ignore # ignore/add/remove/force # Add or remove newline between '}' and 'catch' -nl_brace_catch = ignore # ignore/add/remove/force +nl_brace_catch = ignore # ignore/add/remove/force + +# Add or remove newline between '}' and ']' +nl_brace_square = ignore # ignore/add/remove/force + +# Add or remove newline between '}' and ')' in a function invocation +nl_brace_fparen = ignore # ignore/add/remove/force # Add or remove newline between 'while' and '{' -nl_while_brace = ignore # ignore/add/remove/force +nl_while_brace = ignore # ignore/add/remove/force # Add or remove newline between 'scope (x)' and '{' (D) -nl_scope_brace = ignore # ignore/add/remove/force +nl_scope_brace = ignore # ignore/add/remove/force # Add or remove newline between 'unittest' and '{' (D) -nl_unittest_brace = ignore # ignore/add/remove/force +nl_unittest_brace = ignore # ignore/add/remove/force # Add or remove newline between 'version (x)' and '{' (D) -nl_version_brace = ignore # ignore/add/remove/force +nl_version_brace = ignore # ignore/add/remove/force # Add or remove newline between 'using' and '{' -nl_using_brace = ignore # ignore/add/remove/force +nl_using_brace = ignore # ignore/add/remove/force # Add or remove newline between two open or close braces. # Due to general newline/brace handling, REMOVE may not work. -nl_brace_brace = force # ignore/add/remove/force +nl_brace_brace = force # ignore/add/remove/force # Add or remove newline between 'do' and '{' -nl_do_brace = ignore # ignore/add/remove/force +nl_do_brace = ignore # ignore/add/remove/force # Add or remove newline between '}' and 'while' of 'do' statement -nl_brace_while = ignore # ignore/add/remove/force +nl_brace_while = ignore # ignore/add/remove/force # Add or remove newline between 'switch' and '{' -nl_switch_brace = ignore # ignore/add/remove/force +nl_switch_brace = ignore # ignore/add/remove/force # Add a newline between ')' and '{' if the ')' is on a different line than the if/for/etc. # Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch, and nl_catch_brace. -nl_multi_line_cond = false # false/true +nl_multi_line_cond = false # false/true # Force a newline in a define after the macro name for multi-line defines. -nl_multi_line_define = false # false/true +nl_multi_line_define = false # false/true # Whether to put a newline before 'case' statement -nl_before_case = false # false/true +nl_before_case = false # false/true # Add or remove newline between ')' and 'throw' -nl_before_throw = ignore # ignore/add/remove/force +nl_before_throw = ignore # ignore/add/remove/force # Whether to put a newline after 'case' statement -nl_after_case = false # false/true +nl_after_case = false # false/true # Add or remove a newline between a case ':' and '{'. Overrides nl_after_case. -nl_case_colon_brace = ignore # ignore/add/remove/force +nl_case_colon_brace = ignore # ignore/add/remove/force # Newline between namespace and { -nl_namespace_brace = remove # ignore/add/remove/force +nl_namespace_brace = remove # ignore/add/remove/force # Add or remove newline between 'template<>' and whatever follows. -nl_template_class = add # ignore/add/remove/force +nl_template_class = add # ignore/add/remove/force # Add or remove newline between 'class' and '{' -nl_class_brace = force # ignore/add/remove/force +nl_class_brace = force # ignore/add/remove/force + +# Add or remove newline after each ',' in the class base list +nl_class_init_args = ignore # ignore/add/remove/force # Add or remove newline after each ',' in the constructor member initialization -nl_class_init_args = ignore # ignore/add/remove/force +nl_constr_init_args = ignore # ignore/add/remove/force # Add or remove newline between return type and function name in a function definition -nl_func_type_name = ignore # ignore/add/remove/force +nl_func_type_name = ignore # ignore/add/remove/force # Add or remove newline between return type and function name inside a class {} # Uses nl_func_type_name or nl_func_proto_type_name if set to ignore. -nl_func_type_name_class = ignore # ignore/add/remove/force +nl_func_type_name_class = ignore # ignore/add/remove/force # Add or remove newline between function scope and name in a definition # Controls the newline after '::' in 'void A::f() { }' -nl_func_scope_name = ignore # ignore/add/remove/force +nl_func_scope_name = ignore # ignore/add/remove/force # Add or remove newline between return type and function name in a prototype -nl_func_proto_type_name = ignore # ignore/add/remove/force +nl_func_proto_type_name = ignore # ignore/add/remove/force # Add or remove newline between a function name and the opening '(' -nl_func_paren = ignore # ignore/add/remove/force +nl_func_paren = ignore # ignore/add/remove/force # Add or remove newline between a function name and the opening '(' in the definition -nl_func_def_paren = ignore # ignore/add/remove/force +nl_func_def_paren = ignore # ignore/add/remove/force # Add or remove newline after '(' in a function declaration -nl_func_decl_start = ignore # ignore/add/remove/force +nl_func_decl_start = ignore # ignore/add/remove/force # Add or remove newline after '(' in a function definition -nl_func_def_start = ignore # ignore/add/remove/force +nl_func_def_start = ignore # ignore/add/remove/force # Overrides nl_func_decl_start when there is only one parameter. -nl_func_decl_start_single = ignore # ignore/add/remove/force +nl_func_decl_start_single = ignore # ignore/add/remove/force # Overrides nl_func_def_start when there is only one parameter. -nl_func_def_start_single = ignore # ignore/add/remove/force +nl_func_def_start_single = ignore # ignore/add/remove/force # Add or remove newline after each ',' in a function declaration -nl_func_decl_args = ignore # ignore/add/remove/force +nl_func_decl_args = ignore # ignore/add/remove/force # Add or remove newline after each ',' in a function definition -nl_func_def_args = ignore # ignore/add/remove/force +nl_func_def_args = ignore # ignore/add/remove/force # Add or remove newline before the ')' in a function declaration -nl_func_decl_end = ignore # ignore/add/remove/force +nl_func_decl_end = ignore # ignore/add/remove/force # Add or remove newline before the ')' in a function definition -nl_func_def_end = ignore # ignore/add/remove/force +nl_func_def_end = ignore # ignore/add/remove/force # Overrides nl_func_decl_end when there is only one parameter. -nl_func_decl_end_single = ignore # ignore/add/remove/force +nl_func_decl_end_single = ignore # ignore/add/remove/force # Overrides nl_func_def_end when there is only one parameter. -nl_func_def_end_single = ignore # ignore/add/remove/force +nl_func_def_end_single = ignore # ignore/add/remove/force # Add or remove newline between '()' in a function declaration. -nl_func_decl_empty = remove # ignore/add/remove/force +nl_func_decl_empty = remove # ignore/add/remove/force # Add or remove newline between '()' in a function definition. -nl_func_def_empty = remove # ignore/add/remove/force +nl_func_def_empty = remove # ignore/add/remove/force # Whether to put each OC message parameter on a separate line # See nl_oc_msg_leave_one_liner -nl_oc_msg_args = false # false/true +nl_oc_msg_args = false # false/true # Add or remove newline between function signature and '{' -nl_fdef_brace = force # ignore/add/remove/force +nl_fdef_brace = force # ignore/add/remove/force + +# Add or remove newline between C++11 lambda signature and '{' +nl_cpp_ldef_brace = ignore # ignore/add/remove/force # Add or remove a newline between the return keyword and return expression. -nl_return_expr = remove # ignore/add/remove/force +nl_return_expr = remove # ignore/add/remove/force # Whether to put a newline after semicolons, except in 'for' statements -nl_after_semicolon = true # false/true +nl_after_semicolon = true # false/true + +# Java: Control the newline between the ')' and '{{' of the double brace initializer. +nl_paren_dbrace_open = ignore # ignore/add/remove/force # Whether to put a newline after brace open. # This also adds a newline before the matching brace close. -nl_after_brace_open = true # false/true +nl_after_brace_open = true # false/true # If nl_after_brace_open and nl_after_brace_open_cmt are true, a newline is # placed between the open brace and a trailing single-line comment. -nl_after_brace_open_cmt = false # false/true +nl_after_brace_open_cmt = false # false/true # Whether to put a newline after a virtual brace open with a non-empty body. # These occur in un-braced if/while/do/for statement bodies. -nl_after_vbrace_open = false # false/true +nl_after_vbrace_open = false # false/true # Whether to put a newline after a virtual brace open with an empty body. # These occur in un-braced if/while/do/for statement bodies. -nl_after_vbrace_open_empty = false # false/true +nl_after_vbrace_open_empty = false # false/true # Whether to put a newline after a brace close. # Does not apply if followed by a necessary ';'. -nl_after_brace_close = false # false/true +nl_after_brace_close = false # false/true # Whether to put a newline after a virtual brace close. # Would add a newline before return in: 'if (foo) a++; return;' -nl_after_vbrace_close = false # false/true +nl_after_vbrace_close = false # false/true # Control the newline between the close brace and 'b' in: 'struct { int a; } b;' # Affects enums, unions, and structures. If set to ignore, uses nl_after_brace_close -nl_brace_struct_var = ignore # ignore/add/remove/force +nl_brace_struct_var = ignore # ignore/add/remove/force # Whether to alter newlines in '#define' macros -nl_define_macro = true # false/true +nl_define_macro = true # false/true # Whether to not put blanks after '#ifxx', '#elxx', or before '#endif' -nl_squeeze_ifdef = false # false/true +nl_squeeze_ifdef = false # false/true # Add or remove blank line before 'if' -nl_before_if = ignore # ignore/add/remove/force +nl_before_if = ignore # ignore/add/remove/force # Add or remove blank line after 'if' statement -nl_after_if = ignore # ignore/add/remove/force +nl_after_if = ignore # ignore/add/remove/force # Add or remove blank line before 'for' -nl_before_for = ignore # ignore/add/remove/force +nl_before_for = ignore # ignore/add/remove/force # Add or remove blank line after 'for' statement -nl_after_for = ignore # ignore/add/remove/force +nl_after_for = ignore # ignore/add/remove/force # Add or remove blank line before 'while' -nl_before_while = ignore # ignore/add/remove/force +nl_before_while = ignore # ignore/add/remove/force # Add or remove blank line after 'while' statement -nl_after_while = ignore # ignore/add/remove/force +nl_after_while = ignore # ignore/add/remove/force # Add or remove blank line before 'switch' -nl_before_switch = ignore # ignore/add/remove/force +nl_before_switch = ignore # ignore/add/remove/force # Add or remove blank line after 'switch' statement -nl_after_switch = ignore # ignore/add/remove/force +nl_after_switch = ignore # ignore/add/remove/force # Add or remove blank line before 'do' -nl_before_do = ignore # ignore/add/remove/force +nl_before_do = ignore # ignore/add/remove/force # Add or remove blank line after 'do/while' statement -nl_after_do = ignore # ignore/add/remove/force +nl_after_do = ignore # ignore/add/remove/force # Whether to double-space commented-entries in struct/enum -nl_ds_struct_enum_cmt = false # false/true +nl_ds_struct_enum_cmt = false # false/true # Whether to double-space before the close brace of a struct/union/enum # (lower priority than 'eat_blanks_before_close_brace') -nl_ds_struct_enum_close_brace = false # false/true +nl_ds_struct_enum_close_brace = false # false/true # Add or remove a newline around a class colon. -# Related to pos_class_colon, nl_class_init_args, and pos_comma. -nl_class_colon = ignore # ignore/add/remove/force +# Related to pos_class_colon, nl_class_init_args, and pos_class_comma. +nl_class_colon = ignore # ignore/add/remove/force + +# Add or remove a newline around a class constructor colon. +# Related to pos_constr_colon, nl_constr_init_args, and pos_constr_comma. +nl_constr_colon = ignore # ignore/add/remove/force # Change simple unbraced if statements into a one-liner # 'if(b)\n i++;' => 'if(b) i++;' -nl_create_if_one_liner = false # false/true +nl_create_if_one_liner = false # false/true # Change simple unbraced for statements into a one-liner # 'for (i=0;i<5;i++)\n foo(i);' => 'for (i=0;i<5;i++) foo(i);' -nl_create_for_one_liner = false # false/true +nl_create_for_one_liner = false # false/true # Change simple unbraced while statements into a one-liner # 'while (i<5)\n foo(i++);' => 'while (i<5) foo(i++);' -nl_create_while_one_liner = false # false/true +nl_create_while_one_liner = false # false/true # # Positioning options # # The position of arithmetic operators in wrapped expressions -pos_arith = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force +pos_arith = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of assignment in wrapped expressions. # Do not affect '=' followed by '{' -pos_assign = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force +pos_assign = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of boolean operators in wrapped expressions -pos_bool = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force +pos_bool = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of comparison operators in wrapped expressions -pos_compare = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force +pos_compare = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of conditional (b ? t : f) operators in wrapped expressions -pos_conditional = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force +pos_conditional = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of the comma in wrapped expressions -pos_comma = trail # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force +pos_comma = trail # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force + +# The position of the comma in the class base list +pos_class_comma = trail # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of the comma in the constructor initialization list -pos_class_comma = trail # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force +pos_constr_comma = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force + +# The position of colons between class and base class list +pos_class_colon = lead_force # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of colons between constructor and member initialization -pos_class_colon = lead_force # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force +pos_constr_colon = lead # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # # Line Splitting options # # Try to limit code width to N number of columns -code_width = 0 # number +code_width = 0 # number # Whether to fully split long 'for' statements at semi-colons -ls_for_split_full = true # false/true +ls_for_split_full = true # false/true # Whether to fully split long function protos/calls at commas -ls_func_split_full = true # false/true +ls_func_split_full = true # false/true # Whether to split lines as close to code_width as possible and ignore some groupings -ls_code_width = false # false/true +ls_code_width = false # false/true # # Blank line options # # The maximum consecutive newlines -nl_max = 2 # number +nl_max = 2 # number # The number of newlines after a function prototype, if followed by another function prototype -nl_after_func_proto = 0 # number +nl_after_func_proto = 0 # number # The number of newlines after a function prototype, if not followed by another function prototype -nl_after_func_proto_group = 0 # number +nl_after_func_proto_group = 0 # number # The number of newlines after '}' of a multi-line function body -nl_after_func_body = 0 # number +nl_after_func_body = 0 # number # The number of newlines after '}' of a multi-line function body in a class declaration -nl_after_func_body_class = 0 # number +nl_after_func_body_class = 0 # number # The number of newlines after '}' of a single line function body -nl_after_func_body_one_liner = 0 # number +nl_after_func_body_one_liner = 0 # number # The minimum number of newlines before a multi-line comment. # Doesn't apply if after a brace open or another multi-line comment. -nl_before_block_comment = 0 # number +nl_before_block_comment = 0 # number # The minimum number of newlines before a single-line C comment. # Doesn't apply if after a brace open or other single-line C comments. -nl_before_c_comment = 0 # number +nl_before_c_comment = 0 # number # The minimum number of newlines before a CPP comment. # Doesn't apply if after a brace open or other CPP comments. -nl_before_cpp_comment = 0 # number +nl_before_cpp_comment = 0 # number # Whether to force a newline after a multi-line comment. -nl_after_multiline_comment = false # false/true +nl_after_multiline_comment = false # false/true # The number of newlines after '}' or ';' of a struct/enum/union definition -nl_after_struct = 0 # number +nl_after_struct = 0 # number # The number of newlines after '}' or ';' of a class definition -nl_after_class = 0 # number +nl_after_class = 0 # number # The number of newlines before a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label. # Will not change the newline count if after a brace open. # 0 = No change. -nl_before_access_spec = 2 # number +nl_before_access_spec = 2 # number # The number of newlines after a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label. # 0 = No change. -nl_after_access_spec = 1 # number +nl_after_access_spec = 1 # number # The number of newlines between a function def and the function comment. # 0 = No change. -nl_comment_func_def = 0 # number +nl_comment_func_def = 0 # number # The number of newlines after a try-catch-finally block that isn't followed by a brace close. # 0 = No change. -nl_after_try_catch_finally = 0 # number +nl_after_try_catch_finally = 0 # number # The number of newlines before and after a property, indexer or event decl. # 0 = No change. -nl_around_cs_property = 0 # number +nl_around_cs_property = 0 # number # The number of newlines between the get/set/add/remove handlers in C#. # 0 = No change. -nl_between_get_set = 0 # number +nl_between_get_set = 0 # number # Add or remove newline between C# property and the '{' -nl_property_brace = ignore # ignore/add/remove/force +nl_property_brace = ignore # ignore/add/remove/force # Whether to remove blank lines after '{' -eat_blanks_after_open_brace = true # false/true +eat_blanks_after_open_brace = true # false/true # Whether to remove blank lines before '}' -eat_blanks_before_close_brace = true # false/true +eat_blanks_before_close_brace = true # false/true # How aggressively to remove extra newlines not in preproc. # 0: No change # 1: Remove most newlines not handled by other config # 2: Remove all newlines and reformat completely by config -nl_remove_extra_newlines = 0 # number +nl_remove_extra_newlines = 0 # number # Whether to put a blank line before 'return' statements, unless after an open brace. -nl_before_return = false # false/true +nl_before_return = false # false/true # Whether to put a blank line after 'return' statements, unless followed by a close brace. -nl_after_return = false # false/true +nl_after_return = false # false/true # Whether to put a newline after a Java annotation statement. # Only affects annotations that are after a newline. -nl_after_annotation = ignore # ignore/add/remove/force +nl_after_annotation = ignore # ignore/add/remove/force # Controls the newline between two annotations. -nl_between_annotation = ignore # ignore/add/remove/force +nl_between_annotation = ignore # ignore/add/remove/force # # Code modifying options (non-whitespace) # # Add or remove braces on single-line 'do' statement -mod_full_brace_do = ignore # ignore/add/remove/force +mod_full_brace_do = ignore # ignore/add/remove/force # Add or remove braces on single-line 'for' statement -mod_full_brace_for = ignore # ignore/add/remove/force +mod_full_brace_for = ignore # ignore/add/remove/force # Add or remove braces on single-line function definitions. (Pawn) -mod_full_brace_function = ignore # ignore/add/remove/force +mod_full_brace_function = ignore # ignore/add/remove/force # Add or remove braces on single-line 'if' statement. Will not remove the braces if they contain an 'else'. -mod_full_brace_if = ignore # ignore/add/remove/force +mod_full_brace_if = ignore # ignore/add/remove/force # Make all if/elseif/else statements in a chain be braced or not. Overrides mod_full_brace_if. # If any must be braced, they are all braced. If all can be unbraced, then the braces are removed. -mod_full_brace_if_chain = false # false/true +mod_full_brace_if_chain = false # false/true # Don't remove braces around statements that span N newlines -mod_full_brace_nl = 0 # number +mod_full_brace_nl = 0 # number # Add or remove braces on single-line 'while' statement -mod_full_brace_while = ignore # ignore/add/remove/force +mod_full_brace_while = ignore # ignore/add/remove/force # Add or remove braces on single-line 'using ()' statement -mod_full_brace_using = ignore # ignore/add/remove/force +mod_full_brace_using = ignore # ignore/add/remove/force # Add or remove unnecessary paren on 'return' statement -mod_paren_on_return = ignore # ignore/add/remove/force +mod_paren_on_return = ignore # ignore/add/remove/force # Whether to change optional semicolons to real semicolons -mod_pawn_semicolon = false # false/true +mod_pawn_semicolon = false # false/true # Add parens on 'while' and 'if' statement around bools -mod_full_paren_if_bool = false # false/true +mod_full_paren_if_bool = false # false/true # Whether to remove superfluous semicolons -mod_remove_extra_semicolon = true # false/true +mod_remove_extra_semicolon = true # false/true # If a function body exceeds the specified number of newlines and doesn't have a comment after # the close brace, a comment will be added. -mod_add_long_function_closebrace_comment = 0 # number +mod_add_long_function_closebrace_comment = 0 # number + +# If a namespace body exceeds the specified number of newlines and doesn't have a comment after +# the close brace, a comment will be added. +mod_add_long_namespace_closebrace_comment = 0 # number # If a switch body exceeds the specified number of newlines and doesn't have a comment after # the close brace, a comment will be added. -mod_add_long_switch_closebrace_comment = 0 # number +mod_add_long_switch_closebrace_comment = 0 # number # If an #ifdef body exceeds the specified number of newlines and doesn't have a comment after # the #endif, a comment will be added. -mod_add_long_ifdef_endif_comment = 0 # number +mod_add_long_ifdef_endif_comment = 0 # number # If an #ifdef or #else body exceeds the specified number of newlines and doesn't have a comment after # the #else, a comment will be added. -mod_add_long_ifdef_else_comment = 0 # number +mod_add_long_ifdef_else_comment = 0 # number # If TRUE, will sort consecutive single-line 'import' statements [Java, D] -mod_sort_import = false # false/true +mod_sort_import = false # false/true # If TRUE, will sort consecutive single-line 'using' statements [C#] -mod_sort_using = false # false/true +mod_sort_using = false # false/true # If TRUE, will sort consecutive single-line '#include' statements [C/C++] and '#import' statements [Obj-C] # This is generally a bad idea, as it may break your code. -mod_sort_include = false # false/true +mod_sort_include = false # false/true # If TRUE, it will move a 'break' that appears after a fully braced 'case' before the close brace. -mod_move_case_break = false # false/true +mod_move_case_break = false # false/true # Will add or remove the braces around a fully braced case statement. # Will only remove the braces if there are no variable declarations in the block. -mod_case_brace = ignore # ignore/add/remove/force +mod_case_brace = ignore # ignore/add/remove/force # If TRUE, it will remove a void 'return;' that appears as the last statement in a function. -mod_remove_empty_return = false # false/true +mod_remove_empty_return = false # false/true # # Comment modifications # # Try to wrap comments at cmt_width columns -cmt_width = 0 # number +cmt_width = 0 # number # Set the comment reflow mode (default: 0) # 0: no reflowing (apart from the line wrapping due to cmt_width) # 1: no touching at all # 2: full reflow -cmt_reflow_mode = 0 # number +cmt_reflow_mode = 0 # number + +# Whether to convert all tabs to spaces in comments. Default is to leave tabs inside comments alone, unless used for indenting. +cmt_convert_tab_to_spaces = true # false/true # If false, disable all multi-line comment changes, including cmt_width. keyword substitution, and leading chars. # Default is true. -cmt_indent_multi = false # false/true +cmt_indent_multi = false # false/true # Whether to group c-comments that look like they are in a block -cmt_c_group = false # false/true +cmt_c_group = false # false/true # Whether to put an empty '/*' on the first line of the combined c-comment -cmt_c_nl_start = false # false/true +cmt_c_nl_start = false # false/true # Whether to put a newline before the closing '*/' of the combined c-comment -cmt_c_nl_end = false # false/true +cmt_c_nl_end = false # false/true # Whether to group cpp-comments that look like they are in a block -cmt_cpp_group = false # false/true +cmt_cpp_group = false # false/true # Whether to put an empty '/*' on the first line of the combined cpp-comment -cmt_cpp_nl_start = false # false/true +cmt_cpp_nl_start = false # false/true # Whether to put a newline before the closing '*/' of the combined cpp-comment -cmt_cpp_nl_end = false # false/true +cmt_cpp_nl_end = false # false/true # Whether to change cpp-comments into c-comments -cmt_cpp_to_c = false # false/true +cmt_cpp_to_c = false # false/true # Whether to put a star on subsequent comment lines -cmt_star_cont = false # false/true +cmt_star_cont = false # false/true # The number of spaces to insert at the start of subsequent comment lines -cmt_sp_before_star_cont = 0 # number +cmt_sp_before_star_cont = 0 # number # The number of spaces to insert after the star on subsequent comment lines -cmt_sp_after_star_cont = 0 # number +cmt_sp_after_star_cont = 0 # number # For multi-line comments with a '*' lead, remove leading spaces if the first and last lines of # the comment are the same length. Default=True -cmt_multi_check_last = true # false/true +cmt_multi_check_last = true # false/true # The filename that contains text to insert at the head of a file if the file doesn't start with a C/C++ comment. # Will substitute $(filename) with the current file's name. -cmt_insert_file_header = "" # string +cmt_insert_file_header = "" # string # The filename that contains text to insert at the end of a file if the file doesn't end with a C/C++ comment. # Will substitute $(filename) with the current file's name. -cmt_insert_file_footer = "" # string +cmt_insert_file_footer = "" # string # The filename that contains text to insert before a function implementation if the function isn't preceded with a C/C++ comment. # Will substitute $(function) with the function name and $(javaparam) with the javadoc @param and @return stuff. # Will also substitute $(fclass) with the class name: void CFoo::Bar() { ... } -cmt_insert_func_header = "" # string +cmt_insert_func_header = "" # string # The filename that contains text to insert before a class if the class isn't preceded with a C/C++ comment. # Will substitute $(class) with the class name. -cmt_insert_class_header = "" # string +cmt_insert_class_header = "" # string -# The filename that contains text to insert before a Obj-C message specification if the method isn't preceeded with a C/C++ comment. +# The filename that contains text to insert before a Obj-C message specification if the method isn't preceded with a C/C++ comment. # Will substitute $(message) with the function name and $(javaparam) with the javadoc @param and @return stuff. -cmt_insert_oc_msg_header = "" # string +cmt_insert_oc_msg_header = "" # string # If a preprocessor is encountered when stepping backwards from a function name, then # this option decides whether the comment should be inserted. # Affects cmt_insert_oc_msg_header, cmt_insert_func_header and cmt_insert_class_header. -cmt_insert_before_preproc = false # false/true +cmt_insert_before_preproc = false # false/true # # Preprocessor options # -# Control indent of preprocessors inside #if blocks at brace level 0 -pp_indent = ignore # ignore/add/remove/force +# Control indent of preprocessors inside #if blocks at brace level 0 (file-level) +pp_indent = ignore # ignore/add/remove/force # Whether to indent #if/#else/#endif at the brace level (true) or from column 1 (false) -pp_indent_at_level = false # false/true +pp_indent_at_level = false # false/true -# If pp_indent_at_level=false, specifies the number of columns to indent per level. Default=1. -pp_indent_count = 1 # number +# Specifies the number of columns to indent preprocessors per level at brace level 0 (file-level). +# If pp_indent_at_level=false, specifies the number of columns to indent preprocessors per level at brace level > 0 (function-level). +# Default=1. +pp_indent_count = 1 # number # Add or remove space after # based on pp_level of #if blocks -pp_space = ignore # ignore/add/remove/force +pp_space = ignore # ignore/add/remove/force # Sets the number of spaces added with pp_space -pp_space_count = 0 # number +pp_space_count = 0 # number # The indent for #region and #endregion in C# and '#pragma region' in C/C++ -pp_indent_region = 0 # number +pp_indent_region = 0 # number # Whether to indent the code between #region and #endregion -pp_region_indent_code = false # false/true +pp_region_indent_code = false # false/true -# If pp_indent_at_level=true, sets the indent for #if, #else, and #endif when not at file-level -pp_indent_if = 0 # number +# If pp_indent_at_level=true, sets the indent for #if, #else, and #endif when not at file-level. +# 0: indent preprocessors using output_tab_size. +# >0: column at which all preprocessors will be indented. +pp_indent_if = 0 # number -# Control whether to indent the code between #if, #else and #endif when not at file-level -pp_if_indent_code = false # false/true +# Control whether to indent the code between #if, #else and #endif. +pp_if_indent_code = false # false/true # Whether to indent '#define' at the brace level (true) or from column 1 (false) -pp_define_at_level = false # false/true +pp_define_at_level = false # false/true # You can force a token to be a type with the 'type' option. # Example: @@ -1576,3 +1686,8 @@ pp_define_at_level = false # false/true # all tokens are separated by any mix of ',' commas, '=' equal signs # and whitespace (space, tab) # +# You can add support for other file extensions using the 'file_ext' command. +# The first arg is the language name used with the '-l' option. +# The remaining args are file extensions, matched with 'endswith'. +# file_ext CPP .ch .cxx .cpp.in +# diff --git a/tests/algo/test_parallel_sort.cpp b/tests/algo/test_parallel_sort.cpp index 914afaeec..cb5672e34 100644 --- a/tests/algo/test_parallel_sort.cpp +++ b/tests/algo/test_parallel_sort.cpp @@ -197,7 +197,7 @@ int main(int argc, const char** argv) if (!strcmp(argv[5], "p")) //parallel { stxxl::SETTINGS::native_merge = false; - //parallel_settings.multiway_merge_minimal_n = 1024; //leave as default + //parallel_settings.multiway_merge_minimal_n = 1024; //leave as default } else if (!strcmp(argv[5], "s")) //sequential { diff --git a/tests/containers/hash_map/test_hash_map.cpp b/tests/containers/hash_map/test_hash_map.cpp index e26cfbf5f..8d559b9d9 100644 --- a/tests/containers/hash_map/test_hash_map.cpp +++ b/tests/containers/hash_map/test_hash_map.cpp @@ -96,8 +96,8 @@ struct cmp_structA // forced instantiation of a struct template class stxxl::unordered_map< - structA, structB, hash_structA, cmp_structA, 4* 1024, 4 - >; + structA, structB, hash_structA, cmp_structA, 4* 1024, 4 + >; void basic_test() { diff --git a/tests/containers/ppq/test_ppq.cpp b/tests/containers/ppq/test_ppq.cpp index 70b8a7073..ecceb73d5 100644 --- a/tests/containers/ppq/test_ppq.cpp +++ b/tests/containers/ppq/test_ppq.cpp @@ -56,12 +56,12 @@ struct my_cmp : std::binary_function // greater // forced instantiation template class stxxl::parallel_priority_queue< - my_type, my_cmp, - STXXL_DEFAULT_ALLOC_STRATEGY, - STXXL_DEFAULT_BLOCK_SIZE(ValueType), /* BlockSize */ - 1* 1024L* 1024L* 1024L, /* RamSize */ - 0 /* MaxItems */ - >; + my_type, my_cmp, + STXXL_DEFAULT_ALLOC_STRATEGY, + STXXL_DEFAULT_BLOCK_SIZE(ValueType), /* BlockSize */ + 1* 1024L* 1024L* 1024L, /* RamSize */ + 0 /* MaxItems */ + >; typedef stxxl::parallel_priority_queue< my_type, my_cmp, diff --git a/tests/containers/test_matrix.cpp b/tests/containers/test_matrix.cpp index 0fce9a5eb..0eb898a94 100644 --- a/tests/containers/test_matrix.cpp +++ b/tests/containers/test_matrix.cpp @@ -165,8 +165,8 @@ void test1(int rank) // create three matrices matrix_type * a = new matrix_type(bs, rank, rank), - * b = new matrix_type(bs, rank, rank), - * c = new matrix_type(bs, rank, rank); + * b = new matrix_type(bs, rank, rank), + * c = new matrix_type(bs, rank, rank); stxxl::stats_data stats_before, stats_after; stxxl::matrix_operation_statistic_data matrix_stats_before, matrix_stats_after; @@ -299,8 +299,8 @@ void test2(int rank, int mult_algo_num, int sched_algo_num) block_scheduler_type& bs = *bs_ptr; matrix_type * a = new matrix_type(bs, rank, rank), - * b = new matrix_type(bs, rank, rank), - * c = new matrix_type(bs, rank, rank); + * b = new matrix_type(bs, rank, rank), + * c = new matrix_type(bs, rank, rank); stxxl::stats_data stats_before, stats_after; stxxl::matrix_operation_statistic_data matrix_stats_before, matrix_stats_after; diff --git a/tests/containers/test_pqueue.cpp b/tests/containers/test_pqueue.cpp index 3615b015f..ad2130f0d 100644 --- a/tests/containers/test_pqueue.cpp +++ b/tests/containers/test_pqueue.cpp @@ -61,8 +61,8 @@ struct my_cmp : std::binary_function // greater // forced instantiation template class stxxl::PRIORITY_QUEUE_GENERATOR< - my_type, my_cmp, 32* 1024* 1024, volume / sizeof(my_type) - >; + my_type, my_cmp, 32* 1024* 1024, volume / sizeof(my_type) + >; int main() { diff --git a/tests/parallel/bench_multiway_merge.cpp b/tests/parallel/bench_multiway_merge.cpp index 6db140537..b26161612 100644 --- a/tests/parallel/bench_multiway_merge.cpp +++ b/tests/parallel/bench_multiway_merge.cpp @@ -276,16 +276,16 @@ void test_multiway_merge(unsigned int seq_count, const size_t seq_size) << " total_size=" << total_size << " total_bytes=" << total_bytes #if STXXL_PARALLEL - << " num_threads=" << omp_get_max_threads() + << " num_threads=" << omp_get_max_threads() #else - << " num_threads=1" + << " num_threads=1" #endif - << " time=" << spt.timer().seconds() - << " inner_repeats=" << g_inner_repeat - << " outer_repeats=" << g_outer_repeat - << " time/item[ns]=" - << spt.timer().seconds() / g_inner_repeat / total_size * 1e9 - << std::endl; + << " time=" << spt.timer().seconds() + << " inner_repeats=" << g_inner_repeat + << " outer_repeats=" << g_outer_repeat + << " time/item[ns]=" + << spt.timer().seconds() / g_inner_repeat / total_size * 1e9 + << std::endl; } STXXL_CHECK(stxxl::is_sorted(out.begin(), out.end(), cmp)); diff --git a/tools/benchmarks/matrix_benchmark.cpp b/tools/benchmarks/matrix_benchmark.cpp index 929ec9eba..432abc5e8 100644 --- a/tools/benchmarks/matrix_benchmark.cpp +++ b/tools/benchmarks/matrix_benchmark.cpp @@ -118,8 +118,8 @@ int main(int argc, char** argv) bst* b_s = new bst(internal_memory); // the block_scheduler may use internal_memory byte for caching bst& bs = *b_s; mt* a = new mt(bs, rank, rank), - * b = new mt(bs, rank, rank), - * c = new mt(bs, rank, rank); + * b = new mt(bs, rank, rank), + * c = new mt(bs, rank, rank); STXXL_MSG("writing input matrices"); for (mitt mit = a->begin(); mit != a->end(); ++mit) diff --git a/tools/benchmarks/monotonic_pq.cpp b/tools/benchmarks/monotonic_pq.cpp index 773bffcad..8452402d9 100644 --- a/tools/benchmarks/monotonic_pq.cpp +++ b/tools/benchmarks/monotonic_pq.cpp @@ -115,9 +115,9 @@ int main(int argc, char* argv[]) { std::cout << "Usage: " << argv[0] << " [n in MiB]" #if defined(STXXL_PARALLEL) - << " [p threads]" + << " [p threads]" #endif - << std::endl; + << std::endl; return -1; }