<commit_before>/***************************************************************************
 *  containers/test_iterators.cpp
 *
 *  Part of the STXXL. See http://stxxl.sourceforge.net
 *
 *  Copyright (C) 2007 Roman Dementiev <dementiev@ira.uka.de>
 *  Copyright (C) 2009 Andreas Beckmann <beckmann@cs.uni-frankfurt.de>
 *
 *  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 <cassert>
#include <cstring>
#include <deque>
#include <vector>
#include <stxxl.h>

#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100)

template <typename T>
const char * _()
{
    return strchr(STXXL_PRETTY_FUNCTION_NAME, '[');
}

template <typename I>
void dump_iterator_info(I)
{
    STXXL_MSG(STXXL_PRETTY_FUNCTION_NAME);
    STXXL_MSG("  category:        " << _<typename std::iterator_traits<I>::iterator_category>());
    STXXL_MSG("  value_type:      " << _<typename std::iterator_traits<I>::value_type>());
    STXXL_MSG("  difference_type: " << _<typename std::iterator_traits<I>::difference_type>());
    STXXL_MSG("  pointer:         " << _<typename std::iterator_traits<I>::pointer>());
    STXXL_MSG("  reference:       " << _<typename std::iterator_traits<I>::reference>());
}

template <typename T>
struct modify
{
    void operator () (T & obj) const
    {
        ++obj;
    }
};

template <typename Iterator>
bool test_inc_dec(Iterator it)
{
    Iterator i = it;

    ++i;
    i++;
    --i;
    i--;

    assert(it == i);
    return it == i;
}

template <typename Iterator>
bool test_inc_dec_random(Iterator it)
{
    Iterator i = it;

    ++i;
    i = i + 2;
    i++;
    i += 3;
    --i;
    i = i - 3;
    i--;
    i -= 2;

    assert(it == i);
    return it == i;
}

template <typename IteratorA, typename IteratorB, typename Category>
struct test_comparison_lt_gt
{
    void operator() (IteratorA, IteratorB)
    {
        // operators <, <=, >=, > are not available in all iterator categories
    }
};

template <typename IteratorA, typename IteratorB>
struct test_comparison_lt_gt<IteratorA, IteratorB, std::random_access_iterator_tag>
{
    void operator() (IteratorA a, IteratorB b)
    {
        a < b;
        a <= b;
        a > b;
        a >= b;

        b < a;
        b <= a;
        b > a;
        b >= a;
    }
};

template <typename IteratorA, typename IteratorB>
void test_comparison(IteratorA a, IteratorB b)
{
    a == b;
    a != b;

    b == a;
    b != a;

    test_comparison_lt_gt<IteratorA, IteratorB, typename std::iterator_traits<IteratorA>::iterator_category>() (a, b);
}

template <typename Iterator>
void test_operators(Iterator it)
{
    *it;
    it.operator->();
    test_comparison(it, it);
}

template <typename svt>
void test(svt & sv)
{
    typedef const svt csvt;
    typedef typename svt::value_type value_type;

    sv[0] = 108;

    typename svt::iterator svi = sv.begin();
    dump_iterator_info(svi);
    modify<value_type>() (*svi);

    typename svt::const_iterator svci = sv.begin();
    dump_iterator_info(svci);
    //modify<value_type>()(*svci);      // read-only

    typename csvt::iterator xsvi = sv.begin();
    modify<value_type>() (*xsvi);

    // test assignment
    svci = xsvi;
    //xsvi = svci; // not allowed

    typename csvt::const_iterator xsvci = sv.begin();
    //modify<value_type>()(*xsvci);     // read-only

    // test comparison between const and non-const iterators
    test_comparison(svci, xsvi);

    // test increment/decrement
    test_inc_dec(svi);
    test_inc_dec(svci);
    test_inc_dec(xsvi);
    test_inc_dec(xsvci);

    // test operators
    test_operators(svi);
    test_operators(svci);
    test_operators(xsvi);
    test_operators(xsvci);

    // test forward iteration
    for (typename svt::iterator i = sv.begin(); i != sv.end(); ++i) ;

///////////////////////////////////////////////////////////////////////////

    csvt & csv = sv;
    //csv[0] = 108; // read-only

    //typename csvt::iterator csvi = csv.begin();    // read-only
    //modify<value_type>()(*csvi);      // read-only

    typename csvt::const_iterator csvci = csv.begin();
    //modify<value_type>()(*csvci);     // read-only

    //typename svt::iterator xcsvi = csv.begin();    // read-only
    //modify<value_type>()(*xcsvi);     // read-only

    typename svt::const_iterator xcsvci = csv.begin();
    //modify<value_type>()(*csvci);     // read-only

    // test increment/decrement
    test_inc_dec(csvci);
    test_inc_dec(xcsvci);

    // test operators
    test_operators(csvci);
    test_operators(xcsvci);

    // test forward iteration
    for (typename svt::const_iterator ci = sv.begin(); ci != sv.end(); ++ci) ;
}

template <typename svt>
void test_reverse(svt & sv)
{
    typedef const svt csvt;
    typedef typename svt::value_type value_type;

    sv[0] = 108;

    typename svt::reverse_iterator svi = sv.rbegin();
    dump_iterator_info(svi);
    modify<value_type>() (*svi);

    typename svt::const_reverse_iterator svci = sv.rbegin();
    dump_iterator_info(svci);
    //modify<value_type>()(*svci);      // read-only

    typename csvt::reverse_iterator xsvi = sv.rbegin();
    modify<value_type>() (*xsvi);

    // test assignment
    svci = xsvi;
    //xsvi = svci; // not allowed

    typename csvt::const_reverse_iterator xsvci = sv.rbegin();
    //modify<value_type>()(*xsvci);     // read-only

#if !defined(__GNUG__) || (GCC_VERSION >= 40000)
    // test comparison between const and non-const iterators
    test_comparison(svci, xsvi);
#endif

    // test increment/decrement
    test_inc_dec(svi);
    test_inc_dec(svci);
    test_inc_dec(xsvi);
    test_inc_dec(xsvci);

    // test operators
    test_operators(svi);
    test_operators(svci);
    test_operators(xsvi);
    test_operators(xsvci);

    // test forward iteration
    for (typename svt::reverse_iterator i = sv.rbegin(); i != sv.rend(); ++i) ;

///////////////////////////////////////////////////////////////////////////

    csvt & csv = sv;
    //csv[0] = 108; // read-only

    //typename csvt::reverse_iterator csvi = csv.rbegin();    // read-only
    //modify<value_type>()(*csvi);      // read-only

    typename csvt::const_reverse_iterator csvci = csv.rbegin();
    //modify<value_type>()(*csvci);     // read-only

    //typename svt::reverse_iterator xcsvi = csv.rbegin();    // read-only
    //modify<value_type>()(*xcsvi);     // read-only

    typename svt::const_reverse_iterator xcsvci = csv.rbegin();
    //modify<value_type>()(*csvci);     // read-only

    // test increment/decrement
    test_inc_dec(csvci);
    test_inc_dec(xcsvci);

    // test operators
    test_operators(csvci);
    test_operators(xcsvci);

    // test forward iteration
#if !defined(__GNUG__) || (GCC_VERSION >= 40000)
    for (typename svt::const_reverse_iterator ci = sv.rbegin(); ci != sv.rend(); ++ci) ;
#else
    for (typename svt::const_reverse_iterator ci = sv.rbegin(); ci != typename svt::const_reverse_iterator(sv.rend()); ++ci) ;
#endif
}

template <typename svt>
void test_random_access(svt & sv)
{
    typename svt::const_iterator svci = sv.begin();
    typename svt::iterator xsvi = sv.begin();

    // test subtraction of const and non-const iterators
    svci - xsvi;
    xsvi - svci;

    // bracket operators
    svci[0];
    xsvi[0];
    //svci[0] = 1; // read-only
    xsvi[0] = 1;

    // test +, -, +=, -=
    test_inc_dec_random(svci);
    test_inc_dec_random(xsvi);
}

template <typename svt>
void test_random_access_reverse(svt & sv)
{
    typename svt::const_reverse_iterator svcri = sv.rbegin();
    typename svt::reverse_iterator xsvri = sv.rbegin();

#if !defined(__GNUG__) || (GCC_VERSION >= 40000)
    // test subtraction of const and non-const iterators
    svcri - xsvri;
    xsvri - svcri;
#endif

    // bracket operators
    svcri[0];
    xsvri[0];
    //svcri[0] = 1; // read-only
    xsvri[0] = 1;

    // test +, -, +=, -=
    test_inc_dec_random(svcri);
    test_inc_dec_random(xsvri);
}

typedef float key_type;
typedef double data_type;

struct cmp : public std::less<key_type>
{
    static key_type min_value()
    {
        return (std::numeric_limits<key_type>::min)();
    }
    static key_type max_value()
    {
        return (std::numeric_limits<key_type>::max)();
    }
};

template <>
struct modify<std::pair<const key_type, data_type> >
{
    void operator () (std::pair<const key_type, data_type> & obj) const
    {
        ++(obj.second);
    }
};

int main()
{
    std::vector<double> V(8);
    test(V);
    test_reverse(V);
    test_random_access(V);
    test_random_access_reverse(V);

    stxxl::vector<double> Vector(8);
    test(Vector);
    //test_reverse(Vector);
    test_random_access(Vector);
    //test_random_access_reverse(Vector);

#if !defined(__GNUG__) || (GCC_VERSION >= 30400)
    typedef stxxl::map<key_type, data_type, cmp, 4096, 4096> map_type;
    map_type Map(4096 * 10, 4096 * 10);
    Map[4] = 8;
    Map[15] = 16;
    Map[23] = 42;
    test(Map);
#endif

    std::deque<double> D(1);
    test(D);
    test_reverse(D);
    test_random_access(D);
    test_random_access_reverse(D);

    stxxl::deque<double> Deque(1);
    test(Deque);
    //test_reverse(Deque);
    test_random_access(Deque);
    //test_random_access_reverse(Deque);

    return 0;
}

// vim: et:ts=4:sw=4
<commit_msg>dump container type information, too<commit_after>/***************************************************************************
 *  containers/test_iterators.cpp
 *
 *  Part of the STXXL. See http://stxxl.sourceforge.net
 *
 *  Copyright (C) 2007 Roman Dementiev <dementiev@ira.uka.de>
 *  Copyright (C) 2009 Andreas Beckmann <beckmann@cs.uni-frankfurt.de>
 *
 *  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 <cassert>
#include <cstring>
#include <deque>
#include <map>
#include <vector>
#include <stxxl.h>

#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100)

template <typename T>
const char * _()
{
    return strchr(STXXL_PRETTY_FUNCTION_NAME, '[');
}

template <typename I>
void dump_iterator_info(I&)
{
    STXXL_MSG(STXXL_PRETTY_FUNCTION_NAME);
    STXXL_MSG("  category:        " << _<typename std::iterator_traits<I>::iterator_category>());
    STXXL_MSG("  value_type:      " << _<typename std::iterator_traits<I>::value_type>());
    STXXL_MSG("  difference_type: " << _<typename std::iterator_traits<I>::difference_type>());
    STXXL_MSG("  pointer:         " << _<typename std::iterator_traits<I>::pointer>());
    STXXL_MSG("  reference:       " << _<typename std::iterator_traits<I>::reference>());
}

template <typename C>
void dump_container_info(C&)
{
    STXXL_MSG(STXXL_PRETTY_FUNCTION_NAME);
    STXXL_MSG("  value_type:      " << _<typename C::value_type>());
    STXXL_MSG("  size_type:       " << _<typename C::size_type>());
    STXXL_MSG("  difference_type: " << _<typename C::difference_type>());
    STXXL_MSG("  pointer:         " << _<typename C::pointer>());
    STXXL_MSG("  const_pointer:   " << _<typename C::const_pointer>());
    STXXL_MSG("  reference:       " << _<typename C::reference>());
    STXXL_MSG("  const_reference: " << _<typename C::const_reference>());
    STXXL_MSG("  iterator:        " << _<typename C::iterator>());
    STXXL_MSG("  const_iterator:  " << _<typename C::const_iterator>());
}

template <typename T>
struct modify
{
    void operator () (T & obj) const
    {
        ++obj;
    }
};

template <typename Iterator>
bool test_inc_dec(Iterator it)
{
    Iterator i = it;

    ++i;
    i++;
    --i;
    i--;

    assert(it == i);
    return it == i;
}

template <typename Iterator>
bool test_inc_dec_random(Iterator it)
{
    Iterator i = it;

    ++i;
    i = i + 2;
    i++;
    i += 3;
    --i;
    i = i - 3;
    i--;
    i -= 2;

    assert(it == i);
    return it == i;
}

template <typename IteratorA, typename IteratorB, typename Category>
struct test_comparison_lt_gt
{
    void operator() (IteratorA, IteratorB)
    {
        // operators <, <=, >=, > are not available in all iterator categories
    }
};

template <typename IteratorA, typename IteratorB>
struct test_comparison_lt_gt<IteratorA, IteratorB, std::random_access_iterator_tag>
{
    void operator() (IteratorA a, IteratorB b)
    {
        a < b;
        a <= b;
        a > b;
        a >= b;

        b < a;
        b <= a;
        b > a;
        b >= a;
    }
};

template <typename IteratorA, typename IteratorB>
void test_comparison(IteratorA a, IteratorB b)
{
    a == b;
    a != b;

    b == a;
    b != a;

    test_comparison_lt_gt<IteratorA, IteratorB, typename std::iterator_traits<IteratorA>::iterator_category>() (a, b);
}

template <typename Iterator>
void test_operators(Iterator it)
{
    *it;
    it.operator->();
    test_comparison(it, it);
}

template <typename svt>
void test(svt & sv)
{
    dump_container_info(sv);

    typedef const svt csvt;
    typedef typename svt::value_type value_type;

    sv[0] = 108;

    typename svt::iterator svi = sv.begin();
    dump_iterator_info(svi);
    modify<value_type>() (*svi);

    typename svt::const_iterator svci = sv.begin();
    dump_iterator_info(svci);
    //modify<value_type>()(*svci);      // read-only

    typename csvt::iterator xsvi = sv.begin();
    modify<value_type>() (*xsvi);

    // test assignment
    svci = xsvi;
    //xsvi = svci; // not allowed

    typename csvt::const_iterator xsvci = sv.begin();
    //modify<value_type>()(*xsvci);     // read-only

    // test comparison between const and non-const iterators
    test_comparison(svci, xsvi);

    // test increment/decrement
    test_inc_dec(svi);
    test_inc_dec(svci);
    test_inc_dec(xsvi);
    test_inc_dec(xsvci);

    // test operators
    test_operators(svi);
    test_operators(svci);
    test_operators(xsvi);
    test_operators(xsvci);

    // test forward iteration
    for (typename svt::iterator i = sv.begin(); i != sv.end(); ++i) ;

///////////////////////////////////////////////////////////////////////////

    csvt & csv = sv;
    //csv[0] = 108; // read-only

    //typename csvt::iterator csvi = csv.begin();    // read-only
    //modify<value_type>()(*csvi);      // read-only

    typename csvt::const_iterator csvci = csv.begin();
    //modify<value_type>()(*csvci);     // read-only

    //typename svt::iterator xcsvi = csv.begin();    // read-only
    //modify<value_type>()(*xcsvi);     // read-only

    typename svt::const_iterator xcsvci = csv.begin();
    //modify<value_type>()(*csvci);     // read-only

    // test increment/decrement
    test_inc_dec(csvci);
    test_inc_dec(xcsvci);

    // test operators
    test_operators(csvci);
    test_operators(xcsvci);

    // test forward iteration
    for (typename svt::const_iterator ci = sv.begin(); ci != sv.end(); ++ci) ;
}

template <typename svt>
void test_reverse(svt & sv)
{
    dump_container_info(sv);

    typedef const svt csvt;
    typedef typename svt::value_type value_type;

    sv[0] = 108;

    typename svt::reverse_iterator svi = sv.rbegin();
    dump_iterator_info(svi);
    modify<value_type>() (*svi);

    typename svt::const_reverse_iterator svci = sv.rbegin();
    dump_iterator_info(svci);
    //modify<value_type>()(*svci);      // read-only

    typename csvt::reverse_iterator xsvi = sv.rbegin();
    modify<value_type>() (*xsvi);

    // test assignment
    svci = xsvi;
    //xsvi = svci; // not allowed

    typename csvt::const_reverse_iterator xsvci = sv.rbegin();
    //modify<value_type>()(*xsvci);     // read-only

#if !defined(__GNUG__) || (GCC_VERSION >= 40000)
    // test comparison between const and non-const iterators
    test_comparison(svci, xsvi);
#endif

    // test increment/decrement
    test_inc_dec(svi);
    test_inc_dec(svci);
    test_inc_dec(xsvi);
    test_inc_dec(xsvci);

    // test operators
    test_operators(svi);
    test_operators(svci);
    test_operators(xsvi);
    test_operators(xsvci);

    // test forward iteration
    for (typename svt::reverse_iterator i = sv.rbegin(); i != sv.rend(); ++i) ;

///////////////////////////////////////////////////////////////////////////

    csvt & csv = sv;
    //csv[0] = 108; // read-only

    //typename csvt::reverse_iterator csvi = csv.rbegin();    // read-only
    //modify<value_type>()(*csvi);      // read-only

    typename csvt::const_reverse_iterator csvci = csv.rbegin();
    //modify<value_type>()(*csvci);     // read-only

    //typename svt::reverse_iterator xcsvi = csv.rbegin();    // read-only
    //modify<value_type>()(*xcsvi);     // read-only

    typename svt::const_reverse_iterator xcsvci = csv.rbegin();
    //modify<value_type>()(*csvci);     // read-only

    // test increment/decrement
    test_inc_dec(csvci);
    test_inc_dec(xcsvci);

    // test operators
    test_operators(csvci);
    test_operators(xcsvci);

    // test forward iteration
#if !defined(__GNUG__) || (GCC_VERSION >= 40000)
    for (typename svt::const_reverse_iterator ci = sv.rbegin(); ci != sv.rend(); ++ci) ;
#else
    for (typename svt::const_reverse_iterator ci = sv.rbegin(); ci != typename svt::const_reverse_iterator(sv.rend()); ++ci) ;
#endif
}

template <typename svt>
void test_random_access(svt & sv)
{
    typename svt::const_iterator svci = sv.begin();
    typename svt::iterator xsvi = sv.begin();

    // test subtraction of const and non-const iterators
    svci - xsvi;
    xsvi - svci;

    // bracket operators
    svci[0];
    xsvi[0];
    //svci[0] = 1; // read-only
    xsvi[0] = 1;

    // test +, -, +=, -=
    test_inc_dec_random(svci);
    test_inc_dec_random(xsvi);
}

template <typename svt>
void test_random_access_reverse(svt & sv)
{
    typename svt::const_reverse_iterator svcri = sv.rbegin();
    typename svt::reverse_iterator xsvri = sv.rbegin();

#if !defined(__GNUG__) || (GCC_VERSION >= 40000)
    // test subtraction of const and non-const iterators
    svcri - xsvri;
    xsvri - svcri;
#endif

    // bracket operators
    svcri[0];
    xsvri[0];
    //svcri[0] = 1; // read-only
    xsvri[0] = 1;

    // test +, -, +=, -=
    test_inc_dec_random(svcri);
    test_inc_dec_random(xsvri);
}

typedef float key_type;
typedef double data_type;

struct cmp : public std::less<key_type>
{
    static key_type min_value()
    {
        return (std::numeric_limits<key_type>::min)();
    }
    static key_type max_value()
    {
        return (std::numeric_limits<key_type>::max)();
    }
};

template <>
struct modify<std::pair<const key_type, data_type> >
{
    void operator () (std::pair<const key_type, data_type> & obj) const
    {
        ++(obj.second);
    }
};

int main()
{
    std::vector<double> V(8);
    test(V);
    test_reverse(V);
    test_random_access(V);
    test_random_access_reverse(V);

    stxxl::vector<double> Vector(8);
    test(Vector);
    //test_reverse(Vector);
    test_random_access(Vector);
    //test_random_access_reverse(Vector);

    std::map<key_type, data_type, cmp> M;
    M[4] = 8;
    M[15] = 16;
    M[23] = 42;
    test(M);

#if !defined(__GNUG__) || (GCC_VERSION >= 30400)
    typedef stxxl::map<key_type, data_type, cmp, 4096, 4096> map_type;
    map_type Map(4096 * 10, 4096 * 10);
    Map[4] = 8;
    Map[15] = 16;
    Map[23] = 42;
    test(Map);
#endif

    std::deque<double> D(1);
    test(D);
    test_reverse(D);
    test_random_access(D);
    test_random_access_reverse(D);

    stxxl::deque<double> Deque(1);
    test(Deque);
    //test_reverse(Deque);
    test_random_access(Deque);
    //test_random_access_reverse(Deque);

    return 0;
}

// vim: et:ts=4:sw=4
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(XercesPARSERLIAISONDEFINITIONS_HEADER_GUARD_1357924680)
#define XercesPARSERLIAISONDEFINITIONS_HEADER_GUARD_1357924680

#include <Include/PlatformDefinitions.hpp>

#if defined(XALAN_XERCESPARSERLIAISON_BUILD_DLL)

#define XALAN_XERCESPARSERLIAISON_EXPORT XALAN_PLATFORM_EXPORT

#define XALAN_XERCESPARSERLIAISON_EXPORT_FUNCTION(T) XALAN_PLATFORM_EXPORT_FUNCTION(T)

#else

#define XALAN_XERCESPARSERLIAISON_EXPORT XALAN_PLATFORM_IMPORT

#define XALAN_XERCESPARSERLIAISON_EXPORT_FUNCTION(T) XALAN_PLATFORM_IMPORT_FUNCTION(T)

#endif

#endif	// XercesPARSERLIAISONDEFINITIONS_HEADER_GUARD_1357924680
<commit_msg>Include Xerces defs file so the version macros are defined.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(XercesPARSERLIAISONDEFINITIONS_HEADER_GUARD_1357924680)
#define XercesPARSERLIAISONDEFINITIONS_HEADER_GUARD_1357924680

#include <Include/PlatformDefinitions.hpp>

#include <xercesc/util/XercesDefs.hpp>

#if defined(XALAN_XERCESPARSERLIAISON_BUILD_DLL)

#define XALAN_XERCESPARSERLIAISON_EXPORT XALAN_PLATFORM_EXPORT

#define XALAN_XERCESPARSERLIAISON_EXPORT_FUNCTION(T) XALAN_PLATFORM_EXPORT_FUNCTION(T)

#else

#define XALAN_XERCESPARSERLIAISON_EXPORT XALAN_PLATFORM_IMPORT

#define XALAN_XERCESPARSERLIAISON_EXPORT_FUNCTION(T) XALAN_PLATFORM_IMPORT_FUNCTION(T)

#endif

#endif	// XercesPARSERLIAISONDEFINITIONS_HEADER_GUARD_1357924680
<|endoftext|>


<commit_before>// Begin CVS Header
//   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/function/CEvaluationNode.cpp,v $
//   $Revision: 1.34 $
//   $Name:  $
//   $Author: ssahle $
//   $Date: 2007/09/21 15:40:12 $
// End CVS Header

// Copyright (C) 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include "copasi.h"
#include "CEvaluationNode.h"

#include "sbml/math/ASTNode.h"
#include "sbml/ConverterASTNode.h"
#include "sbml/util/List.h"

CEvaluationNode::CPrecedence::CPrecedence(const unsigned C_INT32 & left,
    const unsigned C_INT32 & right):
    left(left),
    right(right)
{}

CEvaluationNode::CPrecedence::CPrecedence(const CPrecedence & src):
    left(src.left),
    right(src.right)
{}

CEvaluationNode::CPrecedence::~CPrecedence() {}

CEvaluationNode * CEvaluationNode::create(const Type & type,
    const std::string & contents)
{
  CEvaluationNode * pNode = NULL;

  switch (CEvaluationNode::type(type))
    {
    case CEvaluationNode::CALL:
      pNode = new CEvaluationNodeCall((CEvaluationNodeCall::SubType) subType(type),
                                      contents);
      break;

    case CEvaluationNode::CHOICE:
      pNode = new CEvaluationNodeChoice((CEvaluationNodeChoice::SubType) subType(type),
                                        contents);
      break;

    case CEvaluationNode::CONSTANT:
      pNode = new CEvaluationNodeConstant((CEvaluationNodeConstant::SubType) subType(type),
                                          contents);
      break;

    case CEvaluationNode::FUNCTION:
      pNode = new CEvaluationNodeFunction((CEvaluationNodeFunction::SubType) subType(type),
                                          contents);
      break;

    case CEvaluationNode::LOGICAL:
      pNode = new CEvaluationNodeLogical((CEvaluationNodeLogical::SubType) subType(type),
                                         contents);
      break;

    case CEvaluationNode::NUMBER:
      pNode = new CEvaluationNodeNumber((CEvaluationNodeNumber::SubType) subType(type),
                                        contents);
      break;

    case CEvaluationNode::OBJECT:
      pNode = new CEvaluationNodeObject((CEvaluationNodeObject::SubType) subType(type),
                                        contents);
      break;

    case CEvaluationNode::OPERATOR:
      pNode = new CEvaluationNodeOperator((CEvaluationNodeOperator::SubType) subType(type),
                                          contents);
      break;

    case CEvaluationNode::STRUCTURE:
      pNode = new CEvaluationNodeStructure((CEvaluationNodeStructure::SubType) subType(type),
                                           contents);
      break;

    case CEvaluationNode::VARIABLE:
      pNode = new CEvaluationNodeVariable((CEvaluationNodeVariable::SubType) subType(type),
                                          contents);
      break;

    case CEvaluationNode::VECTOR:
      pNode = new CEvaluationNodeVector((CEvaluationNodeVector::SubType) subType(type),
                                        contents);
      break;

    case CEvaluationNode::WHITESPACE:
      pNode = new CEvaluationNodeWhiteSpace((CEvaluationNodeWhiteSpace::SubType) subType(type),
                                            contents);
      break;
    }

  return pNode;
}

CEvaluationNode::Type CEvaluationNode::subType(const Type & type)
{return (Type) (type & 0x00FFFFFF);}

CEvaluationNode::Type CEvaluationNode::type(const Type & type)
{return (Type) (type & 0xFF000000);}

CEvaluationNode::CEvaluationNode():
    CCopasiNode<Data>(),
    mType(CEvaluationNode::INVALID),
    mValue(std::numeric_limits<C_FLOAT64>::quiet_NaN()),
    mData(""),
    mPrecedence(PRECEDENCE_DEFAULT)
{}

CEvaluationNode::CEvaluationNode(const Type & type,
                                 const Data & data):
    CCopasiNode<Data>(),
    mType(type),
    mValue(std::numeric_limits<C_FLOAT64>::quiet_NaN()),
    mData(data),
    mPrecedence(PRECEDENCE_DEFAULT)
{assert(mData != "");}

CEvaluationNode::CEvaluationNode(const CEvaluationNode & src):
    CCopasiNode<Data>(src),
    mType(src.mType),
    mValue(src.mValue),
    mData(src.mData),
    mPrecedence(src.mPrecedence)
{assert(mData != "");}

CEvaluationNode::~CEvaluationNode() {}

bool CEvaluationNode::compile(const CEvaluationTree * /* pTree */)
{return true;}

CEvaluationNode::Data CEvaluationNode::getData() const
  {return mData;}

bool CEvaluationNode::setData(const Data & data)
{
  mData = data;
  return true;
}

std::string CEvaluationNode::getInfix() const
  {return mData;}

std::string CEvaluationNode::getDisplayString(const CEvaluationTree * /* pTree */) const
  {return mData;}

std::string CEvaluationNode::getDisplay_C_String(const CEvaluationTree * /* pTree */) const
  {return mData;}

std::string CEvaluationNode::getDisplay_MMD_String(const CEvaluationTree * /* pTree */) const
  {return mData;}

std::string CEvaluationNode::getDisplay_XPP_String(const CEvaluationTree * /* pTree */) const
  {return mData;}

const CEvaluationNode::Type & CEvaluationNode::getType() const
  {return mType;}

bool CEvaluationNode::operator < (const CEvaluationNode & rhs)
{return (mPrecedence.right < rhs.mPrecedence.left);}

CEvaluationNode* CEvaluationNode::copyNode(CEvaluationNode* child1, CEvaluationNode* child2) const
  {
    std::vector<CEvaluationNode*> children;
    if (child1 != NULL) children.push_back(child1);
    if (child2 != NULL) children.push_back(child2);
    return copyNode(children);
  }

CEvaluationNode* CEvaluationNode::copyNode(const std::vector<CEvaluationNode*>& children) const
  {
    //std::cout << " this->getData() " << this->CEvaluationNode::getData() << std::endl;

    CEvaluationNode *newnode = create(getType(), getData());
    std::vector<CEvaluationNode*>::const_iterator it = children.begin(), endit = children.end();
    while (it != endit)
      {
        newnode->addChild(*it);
        ++it;
      }
    return newnode;
  }

CEvaluationNode* CEvaluationNode::copyBranch() const
  {
    std::vector<CEvaluationNode*> children;
    const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(getChild());
    while (child != NULL)
      {
        CEvaluationNode *newchild = NULL;
        newchild = child->copyBranch();
        children.push_back(newchild);
        child = dynamic_cast<const CEvaluationNode*>(child->getSibling());
      }
    children.push_back(NULL);
    CEvaluationNode *newnode = copyNode(children);
    return newnode;
  }

CEvaluationNode* CEvaluationNode::simplifyNode(const std::vector<CEvaluationNode*>& children) const
  {
    CEvaluationNode *newnode = copyNode(children);
    return newnode;
  }

ASTNode* CEvaluationNode::toAST() const
  {
    return new ASTNode();
  }

const C_FLOAT64 * CEvaluationNode::getValuePointer() const
  {return &mValue;}

void CEvaluationNode::writeMathML(std::ostream & /* out */,
                                  const std::vector<std::vector<std::string> > & /* env */,
                                  bool /* expand */,
                                  unsigned C_INT32 /* l */) const
  {}

void CEvaluationNode::printRecursively(std::ostream & os, int indent) const
  {
    int i;

    os << std::endl;

    for (i = 0; i < indent; ++i) os << " ";
    os << "mData: " << mData << std::endl;

    for (i = 0; i < indent; ++i) os << " ";
    os << "mType: " << type(mType) << "  subType: " << subType(mType) << std::endl;

    for (i = 0; i < indent; ++i) os << " ";
    os << "mValue: " << mValue << std::endl;

    CEvaluationNode* tmp;

    tmp = (CEvaluationNode*)getChild();

    while (tmp)
      {
        tmp -> printRecursively(os, indent + 2);
        tmp = (CEvaluationNode*)tmp->getSibling();
      }

    /*    if (getChild())
          ((CEvaluationNode*)getChild())->printRecursively(os, indent + 2);

        if (getSibling())
          ((CEvaluationNode*)getSibling())->printRecursively(os, indent);*/
  }

void CEvaluationNode::printRecursively() const
  {
    this->printRecursively(std::cout, 0);
  }

/**
 * Replaces all LOG10 (AST_FUNCTION_LOG) nodes that have two
 * children with the quotient of two LOG10 nodes with the base
 * as the argument for the divisor LOG10 node.
 */
void CEvaluationNode::replaceLog(ConverterASTNode* sourceNode)
{
  if (sourceNode->getType() == AST_FUNCTION_LOG && sourceNode->getNumChildren() == 2)
    {
      List* l = new List();
      ConverterASTNode* child1 = (ConverterASTNode*)sourceNode->getChild(0);
      ConverterASTNode* child2 = (ConverterASTNode*)sourceNode->getChild(1);
      ConverterASTNode* logNode1 = new ConverterASTNode(AST_FUNCTION_LOG);
      l->add(child1);
      logNode1->setChildren(l);
      ConverterASTNode* logNode2 = new ConverterASTNode(AST_FUNCTION_LOG);
      l = new List();
      l->add(child2);
      logNode2->setChildren(l);
      l = new List();
      l->add(logNode2);
      l->add(logNode1);
      sourceNode->setChildren(l);
      sourceNode->setType(AST_DIVIDE);
    }
}

/**
 * Replaces all root nodes with the corresponding power
 * operator since COPASI does not have the ROOT function.
 */
void CEvaluationNode::replaceRoot(ConverterASTNode* sourceNode)
{
  if (sourceNode->getType() == AST_FUNCTION_ROOT && sourceNode->getNumChildren() == 2)
    {
      ConverterASTNode* child1 = (ConverterASTNode*)sourceNode->getChild(0);
      ConverterASTNode* child2 = (ConverterASTNode*)sourceNode->getChild(1);
      ConverterASTNode* divideNode = new ConverterASTNode(AST_DIVIDE);
      ConverterASTNode* oneNode = new ConverterASTNode(AST_REAL);
      oneNode->setValue(1.0);
      List* l = new List();
      l->add(divideNode);
      divideNode->addChild(oneNode);
      divideNode->addChild(child1);

      List* l2 = new List();
      l2->add(child2);
      l2->add(divideNode);

      sourceNode->setChildren(l2);
      sourceNode->setType(AST_POWER);
    }
}

CEvaluationNode* CEvaluationNode::splitBranch(const CEvaluationNode* splitnode, bool left) const
  {
    if (splitnode == this)
      {
        const CEvaluationNode *child = dynamic_cast<const CEvaluationNode*>(this->getChild());
        if (!child) return NULL;
        if (left)
          {
            return child->copyBranch();
          }
        else
          {
            child = dynamic_cast<const CEvaluationNode*>(child->getSibling());
            if (!child) return NULL;
            return child->copyBranch();
          }
      }
    else
      {
        /*        const CEvaluationNode *child1 = dynamic_cast<const CEvaluationNode*>(getChild());
                CEvaluationNode *newchild1 = NULL;
                CEvaluationNode *newchild2 = NULL;
                if (child1 != NULL)
                  {
                    newchild1 = child1->splitBranch(splitnode, left);
                    const CEvaluationNode *child2 = dynamic_cast<const CEvaluationNode*>(child1->getSibling());
                    if (child2 != NULL)
                      {
                        newchild2 = child2->splitBranch(splitnode, left);
                      }
                  }
                CEvaluationNode *newnode = copyNode(newchild1, newchild2);
                return newnode;*/

        std::vector<CEvaluationNode*> children;
        const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(getChild());
        while (child != NULL)
          {
            CEvaluationNode *newchild = NULL;
            newchild = child->splitBranch(splitnode, left);
            children.push_back(newchild);
            child = dynamic_cast<const CEvaluationNode*>(child->getSibling());
          }
        children.push_back(NULL);
        CEvaluationNode *newnode = copyNode(children);
        return newnode;
      }
  }

const CEvaluationNode* CEvaluationNode::findTopMinus(const std::vector<CFunctionAnalyzer::CValue> & callParameters) const
  {
    if (getType() == (OPERATOR | CEvaluationNodeOperator::MINUS))
      return this;

    if (getType() == (OPERATOR | CEvaluationNodeOperator::MULTIPLY))
      {
        //look at left child recursively
        const CEvaluationNode *child = dynamic_cast<const CEvaluationNode*>(this->getChild());
        const CEvaluationNode *tmp = NULL;
        if (child) tmp = child->findTopMinus(callParameters);
        if (tmp)
          {
            //we have found a minus operator in the branch of the left child. We
            //only want to report this as a split point if the other branch is positive.
            const CEvaluationNode *child2 = dynamic_cast<const CEvaluationNode*>(child->getSibling());
            if (CFunctionAnalyzer::evaluateNode(child2, callParameters).isPositive())
              return tmp;
            else
              return NULL;
          }

        //otherwise look at right child
        const CEvaluationNode *child2 = dynamic_cast<const CEvaluationNode*>(child->getSibling());
        if (child2) tmp = child2->findTopMinus(callParameters);
        if (tmp)
          {
            //we have found a minus operator in the branch of the right child. We
            //only want to report this as a split point if the other branch is positive.
            if (CFunctionAnalyzer::evaluateNode(child, callParameters).isPositive())
              return tmp;
            else
              return NULL;
          }

        //TODO: check if both children contain a minus. This would not be a valid split point.
      }

    if (getType() == (OPERATOR | CEvaluationNodeOperator::DIVIDE))
      {
        //look at left child only (recursively)
        const CEvaluationNode *child = dynamic_cast<const CEvaluationNode*>(this->getChild());
        const CEvaluationNode *tmp = NULL;
        if (child) tmp = child->findTopMinus(callParameters);
        if (tmp) return tmp;
      }

    return NULL;
  }
<commit_msg>adapt to changes in CFunctionAnalyzer<commit_after>// Begin CVS Header
//   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/function/CEvaluationNode.cpp,v $
//   $Revision: 1.35 $
//   $Name:  $
//   $Author: ssahle $
//   $Date: 2007/10/26 12:59:02 $
// End CVS Header

// Copyright (C) 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include "copasi.h"
#include "CEvaluationNode.h"

#include "sbml/math/ASTNode.h"
#include "sbml/ConverterASTNode.h"
#include "sbml/util/List.h"

CEvaluationNode::CPrecedence::CPrecedence(const unsigned C_INT32 & left,
    const unsigned C_INT32 & right):
    left(left),
    right(right)
{}

CEvaluationNode::CPrecedence::CPrecedence(const CPrecedence & src):
    left(src.left),
    right(src.right)
{}

CEvaluationNode::CPrecedence::~CPrecedence() {}

CEvaluationNode * CEvaluationNode::create(const Type & type,
    const std::string & contents)
{
  CEvaluationNode * pNode = NULL;

  switch (CEvaluationNode::type(type))
    {
    case CEvaluationNode::CALL:
      pNode = new CEvaluationNodeCall((CEvaluationNodeCall::SubType) subType(type),
                                      contents);
      break;

    case CEvaluationNode::CHOICE:
      pNode = new CEvaluationNodeChoice((CEvaluationNodeChoice::SubType) subType(type),
                                        contents);
      break;

    case CEvaluationNode::CONSTANT:
      pNode = new CEvaluationNodeConstant((CEvaluationNodeConstant::SubType) subType(type),
                                          contents);
      break;

    case CEvaluationNode::FUNCTION:
      pNode = new CEvaluationNodeFunction((CEvaluationNodeFunction::SubType) subType(type),
                                          contents);
      break;

    case CEvaluationNode::LOGICAL:
      pNode = new CEvaluationNodeLogical((CEvaluationNodeLogical::SubType) subType(type),
                                         contents);
      break;

    case CEvaluationNode::NUMBER:
      pNode = new CEvaluationNodeNumber((CEvaluationNodeNumber::SubType) subType(type),
                                        contents);
      break;

    case CEvaluationNode::OBJECT:
      pNode = new CEvaluationNodeObject((CEvaluationNodeObject::SubType) subType(type),
                                        contents);
      break;

    case CEvaluationNode::OPERATOR:
      pNode = new CEvaluationNodeOperator((CEvaluationNodeOperator::SubType) subType(type),
                                          contents);
      break;

    case CEvaluationNode::STRUCTURE:
      pNode = new CEvaluationNodeStructure((CEvaluationNodeStructure::SubType) subType(type),
                                           contents);
      break;

    case CEvaluationNode::VARIABLE:
      pNode = new CEvaluationNodeVariable((CEvaluationNodeVariable::SubType) subType(type),
                                          contents);
      break;

    case CEvaluationNode::VECTOR:
      pNode = new CEvaluationNodeVector((CEvaluationNodeVector::SubType) subType(type),
                                        contents);
      break;

    case CEvaluationNode::WHITESPACE:
      pNode = new CEvaluationNodeWhiteSpace((CEvaluationNodeWhiteSpace::SubType) subType(type),
                                            contents);
      break;
    }

  return pNode;
}

CEvaluationNode::Type CEvaluationNode::subType(const Type & type)
{return (Type) (type & 0x00FFFFFF);}

CEvaluationNode::Type CEvaluationNode::type(const Type & type)
{return (Type) (type & 0xFF000000);}

CEvaluationNode::CEvaluationNode():
    CCopasiNode<Data>(),
    mType(CEvaluationNode::INVALID),
    mValue(std::numeric_limits<C_FLOAT64>::quiet_NaN()),
    mData(""),
    mPrecedence(PRECEDENCE_DEFAULT)
{}

CEvaluationNode::CEvaluationNode(const Type & type,
                                 const Data & data):
    CCopasiNode<Data>(),
    mType(type),
    mValue(std::numeric_limits<C_FLOAT64>::quiet_NaN()),
    mData(data),
    mPrecedence(PRECEDENCE_DEFAULT)
{assert(mData != "");}

CEvaluationNode::CEvaluationNode(const CEvaluationNode & src):
    CCopasiNode<Data>(src),
    mType(src.mType),
    mValue(src.mValue),
    mData(src.mData),
    mPrecedence(src.mPrecedence)
{assert(mData != "");}

CEvaluationNode::~CEvaluationNode() {}

bool CEvaluationNode::compile(const CEvaluationTree * /* pTree */)
{return true;}

CEvaluationNode::Data CEvaluationNode::getData() const
  {return mData;}

bool CEvaluationNode::setData(const Data & data)
{
  mData = data;
  return true;
}

std::string CEvaluationNode::getInfix() const
  {return mData;}

std::string CEvaluationNode::getDisplayString(const CEvaluationTree * /* pTree */) const
  {return mData;}

std::string CEvaluationNode::getDisplay_C_String(const CEvaluationTree * /* pTree */) const
  {return mData;}

std::string CEvaluationNode::getDisplay_MMD_String(const CEvaluationTree * /* pTree */) const
  {return mData;}

std::string CEvaluationNode::getDisplay_XPP_String(const CEvaluationTree * /* pTree */) const
  {return mData;}

const CEvaluationNode::Type & CEvaluationNode::getType() const
  {return mType;}

bool CEvaluationNode::operator < (const CEvaluationNode & rhs)
{return (mPrecedence.right < rhs.mPrecedence.left);}

CEvaluationNode* CEvaluationNode::copyNode(CEvaluationNode* child1, CEvaluationNode* child2) const
  {
    std::vector<CEvaluationNode*> children;
    if (child1 != NULL) children.push_back(child1);
    if (child2 != NULL) children.push_back(child2);
    return copyNode(children);
  }

CEvaluationNode* CEvaluationNode::copyNode(const std::vector<CEvaluationNode*>& children) const
  {
    //std::cout << " this->getData() " << this->CEvaluationNode::getData() << std::endl;

    CEvaluationNode *newnode = create(getType(), getData());
    std::vector<CEvaluationNode*>::const_iterator it = children.begin(), endit = children.end();
    while (it != endit)
      {
        newnode->addChild(*it);
        ++it;
      }
    return newnode;
  }

CEvaluationNode* CEvaluationNode::copyBranch() const
  {
    std::vector<CEvaluationNode*> children;
    const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(getChild());
    while (child != NULL)
      {
        CEvaluationNode *newchild = NULL;
        newchild = child->copyBranch();
        children.push_back(newchild);
        child = dynamic_cast<const CEvaluationNode*>(child->getSibling());
      }
    children.push_back(NULL);
    CEvaluationNode *newnode = copyNode(children);
    return newnode;
  }

CEvaluationNode* CEvaluationNode::simplifyNode(const std::vector<CEvaluationNode*>& children) const
  {
    CEvaluationNode *newnode = copyNode(children);
    return newnode;
  }

ASTNode* CEvaluationNode::toAST() const
  {
    return new ASTNode();
  }

const C_FLOAT64 * CEvaluationNode::getValuePointer() const
  {return &mValue;}

void CEvaluationNode::writeMathML(std::ostream & /* out */,
                                  const std::vector<std::vector<std::string> > & /* env */,
                                  bool /* expand */,
                                  unsigned C_INT32 /* l */) const
  {}

void CEvaluationNode::printRecursively(std::ostream & os, int indent) const
  {
    int i;

    os << std::endl;

    for (i = 0; i < indent; ++i) os << " ";
    os << "mData: " << mData << std::endl;

    for (i = 0; i < indent; ++i) os << " ";
    os << "mType: " << type(mType) << "  subType: " << subType(mType) << std::endl;

    for (i = 0; i < indent; ++i) os << " ";
    os << "mValue: " << mValue << std::endl;

    CEvaluationNode* tmp;

    tmp = (CEvaluationNode*)getChild();

    while (tmp)
      {
        tmp -> printRecursively(os, indent + 2);
        tmp = (CEvaluationNode*)tmp->getSibling();
      }

    /*    if (getChild())
          ((CEvaluationNode*)getChild())->printRecursively(os, indent + 2);

        if (getSibling())
          ((CEvaluationNode*)getSibling())->printRecursively(os, indent);*/
  }

void CEvaluationNode::printRecursively() const
  {
    this->printRecursively(std::cout, 0);
  }

/**
 * Replaces all LOG10 (AST_FUNCTION_LOG) nodes that have two
 * children with the quotient of two LOG10 nodes with the base
 * as the argument for the divisor LOG10 node.
 */
void CEvaluationNode::replaceLog(ConverterASTNode* sourceNode)
{
  if (sourceNode->getType() == AST_FUNCTION_LOG && sourceNode->getNumChildren() == 2)
    {
      List* l = new List();
      ConverterASTNode* child1 = (ConverterASTNode*)sourceNode->getChild(0);
      ConverterASTNode* child2 = (ConverterASTNode*)sourceNode->getChild(1);
      ConverterASTNode* logNode1 = new ConverterASTNode(AST_FUNCTION_LOG);
      l->add(child1);
      logNode1->setChildren(l);
      ConverterASTNode* logNode2 = new ConverterASTNode(AST_FUNCTION_LOG);
      l = new List();
      l->add(child2);
      logNode2->setChildren(l);
      l = new List();
      l->add(logNode2);
      l->add(logNode1);
      sourceNode->setChildren(l);
      sourceNode->setType(AST_DIVIDE);
    }
}

/**
 * Replaces all root nodes with the corresponding power
 * operator since COPASI does not have the ROOT function.
 */
void CEvaluationNode::replaceRoot(ConverterASTNode* sourceNode)
{
  if (sourceNode->getType() == AST_FUNCTION_ROOT && sourceNode->getNumChildren() == 2)
    {
      ConverterASTNode* child1 = (ConverterASTNode*)sourceNode->getChild(0);
      ConverterASTNode* child2 = (ConverterASTNode*)sourceNode->getChild(1);
      ConverterASTNode* divideNode = new ConverterASTNode(AST_DIVIDE);
      ConverterASTNode* oneNode = new ConverterASTNode(AST_REAL);
      oneNode->setValue(1.0);
      List* l = new List();
      l->add(divideNode);
      divideNode->addChild(oneNode);
      divideNode->addChild(child1);

      List* l2 = new List();
      l2->add(child2);
      l2->add(divideNode);

      sourceNode->setChildren(l2);
      sourceNode->setType(AST_POWER);
    }
}

CEvaluationNode* CEvaluationNode::splitBranch(const CEvaluationNode* splitnode, bool left) const
  {
    if (splitnode == this)
      {
        const CEvaluationNode *child = dynamic_cast<const CEvaluationNode*>(this->getChild());
        if (!child) return NULL;
        if (left)
          {
            return child->copyBranch();
          }
        else
          {
            child = dynamic_cast<const CEvaluationNode*>(child->getSibling());
            if (!child) return NULL;
            return child->copyBranch();
          }
      }
    else
      {
        /*        const CEvaluationNode *child1 = dynamic_cast<const CEvaluationNode*>(getChild());
                CEvaluationNode *newchild1 = NULL;
                CEvaluationNode *newchild2 = NULL;
                if (child1 != NULL)
                  {
                    newchild1 = child1->splitBranch(splitnode, left);
                    const CEvaluationNode *child2 = dynamic_cast<const CEvaluationNode*>(child1->getSibling());
                    if (child2 != NULL)
                      {
                        newchild2 = child2->splitBranch(splitnode, left);
                      }
                  }
                CEvaluationNode *newnode = copyNode(newchild1, newchild2);
                return newnode;*/

        std::vector<CEvaluationNode*> children;
        const CEvaluationNode* child = dynamic_cast<const CEvaluationNode*>(getChild());
        while (child != NULL)
          {
            CEvaluationNode *newchild = NULL;
            newchild = child->splitBranch(splitnode, left);
            children.push_back(newchild);
            child = dynamic_cast<const CEvaluationNode*>(child->getSibling());
          }
        children.push_back(NULL);
        CEvaluationNode *newnode = copyNode(children);
        return newnode;
      }
  }

const CEvaluationNode* CEvaluationNode::findTopMinus(const std::vector<CFunctionAnalyzer::CValue> & callParameters) const
  {
    if (getType() == (OPERATOR | CEvaluationNodeOperator::MINUS))
      return this;

    if (getType() == (OPERATOR | CEvaluationNodeOperator::MULTIPLY))
      {
        //look at left child recursively
        const CEvaluationNode *child = dynamic_cast<const CEvaluationNode*>(this->getChild());
        const CEvaluationNode *tmp = NULL;
        if (child) tmp = child->findTopMinus(callParameters);
        if (tmp)
          {
            //we have found a minus operator in the branch of the left child. We
            //only want to report this as a split point if the other branch is positive.
            const CEvaluationNode *child2 = dynamic_cast<const CEvaluationNode*>(child->getSibling());
            if (CFunctionAnalyzer::evaluateNode(child2, callParameters, CFunctionAnalyzer::NOOBJECT).isPositive())
              return tmp;
            else
              return NULL;
          }

        //otherwise look at right child
        const CEvaluationNode *child2 = dynamic_cast<const CEvaluationNode*>(child->getSibling());
        if (child2) tmp = child2->findTopMinus(callParameters);
        if (tmp)
          {
            //we have found a minus operator in the branch of the right child. We
            //only want to report this as a split point if the other branch is positive.
            if (CFunctionAnalyzer::evaluateNode(child, callParameters, CFunctionAnalyzer::NOOBJECT).isPositive())
              return tmp;
            else
              return NULL;
          }

        //TODO: check if both children contain a minus. This would not be a valid split point.
      }

    if (getType() == (OPERATOR | CEvaluationNodeOperator::DIVIDE))
      {
        //look at left child only (recursively)
        const CEvaluationNode *child = dynamic_cast<const CEvaluationNode*>(this->getChild());
        const CEvaluationNode *tmp = NULL;
        if (child) tmp = child->findTopMinus(callParameters);
        if (tmp) return tmp;
      }

    return NULL;
  }
<|endoftext|>


<commit_before>#pragma once

#include <regex>
#include <optional>

#include "acmacs-base/fmt.hh"

// ======================================================================
// Support for multiple regex and replacements, see acmacs-virus/cc/reassortant.cc
// ======================================================================

namespace acmacs::regex
{
    struct look_replace_t
    {
        const std::regex look_for;
        std::vector<const char*> fmt;
    };

    // returns pair of empty strings if no matches found
    template <typename Container> std::optional<std::vector<std::string>> scan_replace(std::string_view source, const Container& scan_data)
    {
        for (const auto& entry : scan_data) {
            if (std::cmatch match; std::regex_search(std::begin(source), std::end(source), match, entry.look_for)) {
                std::vector<std::string> result(entry.fmt.size());
                std::transform(std::begin(entry.fmt), std::end(entry.fmt), std::begin(result), [&match](const char* fmt) { return match.format(fmt); });
                return result;
            }
        }
        return {};
    }

}

// ======================================================================
// fmt support for std::smatch and std::cmatch
// ======================================================================

// specialization below follows fmt lib description, but it does not work due to ambiguity with
// template <typename RangeT, typename Char> struct formatter<RangeT, Char, enable_if_t<fmt::is_range<RangeT, Char>::value>>
//
// template <typename Match>  struct fmt::formatter<Match, std::enable_if_t<std::is_same_v<Match, std::smatch> || std::is_same_v<Match, std::cmatch>, char>> : fmt::formatter<acmacs::fmt_default_formatter>

// ----------------------------------------------------------------------

namespace acmacs
{
    template <typename Match> struct fmt_regex_match_formatter {};
}

template <typename Match> struct fmt::formatter<acmacs::fmt_regex_match_formatter<Match>> : fmt::formatter<acmacs::fmt_default_formatter>
{
    template <typename FormatCtx> auto format(const Match& mr, FormatCtx& ctx) {
        format_to(ctx.out(), "\"{}\" -> ({})[", mr.str(0), mr.size());
        for (size_t nr = 1; nr <= mr.size(); ++nr)
            format_to(ctx.out(), " {}:\"{}\"", nr, mr.str(nr));
        format_to(ctx.out(), " ]");
        return ctx.out();
    }
};

template <> struct fmt::formatter<std::smatch> : fmt::formatter<acmacs::fmt_regex_match_formatter<std::smatch>>
{
};

template <> struct fmt::formatter<std::cmatch> : fmt::formatter<acmacs::fmt_regex_match_formatter<std::cmatch>>
{
};

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>common regex constant<commit_after>#pragma once

#include <regex>
#include <optional>

#include "acmacs-base/fmt.hh"

// ======================================================================
// Support for multiple regex and replacements, see acmacs-virus/cc/reassortant.cc
// ======================================================================

namespace acmacs::regex
{
    constexpr auto icase = std::regex::icase | std::regex::ECMAScript | std::regex::optimize;

    struct look_replace_t
    {
        const std::regex look_for;
        std::vector<const char*> fmt;
    };

    // returns pair of empty strings if no matches found
    template <typename Container> std::optional<std::vector<std::string>> scan_replace(std::string_view source, const Container& scan_data)
    {
        for (const auto& entry : scan_data) {
            if (std::cmatch match; std::regex_search(std::begin(source), std::end(source), match, entry.look_for)) {
                std::vector<std::string> result(entry.fmt.size());
                std::transform(std::begin(entry.fmt), std::end(entry.fmt), std::begin(result), [&match](const char* fmt) { return match.format(fmt); });
                return result;
            }
        }
        return {};
    }

}

// ======================================================================
// fmt support for std::smatch and std::cmatch
// ======================================================================

// specialization below follows fmt lib description, but it does not work due to ambiguity with
// template <typename RangeT, typename Char> struct formatter<RangeT, Char, enable_if_t<fmt::is_range<RangeT, Char>::value>>
//
// template <typename Match>  struct fmt::formatter<Match, std::enable_if_t<std::is_same_v<Match, std::smatch> || std::is_same_v<Match, std::cmatch>, char>> : fmt::formatter<acmacs::fmt_default_formatter>

// ----------------------------------------------------------------------

namespace acmacs
{
    template <typename Match> struct fmt_regex_match_formatter {};
}

template <typename Match> struct fmt::formatter<acmacs::fmt_regex_match_formatter<Match>> : fmt::formatter<acmacs::fmt_default_formatter>
{
    template <typename FormatCtx> auto format(const Match& mr, FormatCtx& ctx) {
        format_to(ctx.out(), "\"{}\" -> ({})[", mr.str(0), mr.size());
        for (size_t nr = 1; nr <= mr.size(); ++nr)
            format_to(ctx.out(), " {}:\"{}\"", nr, mr.str(nr));
        format_to(ctx.out(), " ]");
        return ctx.out();
    }
};

template <> struct fmt::formatter<std::smatch> : fmt::formatter<acmacs::fmt_regex_match_formatter<std::smatch>>
{
};

template <> struct fmt::formatter<std::cmatch> : fmt::formatter<acmacs::fmt_regex_match_formatter<std::cmatch>>
{
};

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>/*
  Copyright (c) 2014-2015 DataStax

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

#ifndef __CASS_STREAM_MANAGER_HPP_INCLUDED__
#define __CASS_STREAM_MANAGER_HPP_INCLUDED__

#include "scoped_ptr.hpp"

#include <assert.h>
#include <stdint.h>
#include <string.h>

#include <google/sparse_hash_map>

#if defined(_MSC_VER)
#include <intrin.h>
#endif

namespace cass {

template <class T>
class StreamManager {
public:
  StreamManager(int protocol_version)
      : max_streams_(1 << (num_bytes_for_stream(protocol_version) * 8 - 1))
      , num_words_(max_streams_ / NUM_BITS_PER_WORD)
      , offset_(0)
      , words_(new word_t[num_words_]) {
    pending_.set_deleted_key(-1);
    memset(words_.get(), 0xFF, sizeof(word_t) * num_words_);
  }

  int acquire(const T& item) {
    int stream = acquire_stream();
    if (stream < 0) return -1;
    pending_[stream] = item;
    return stream;
  }

  void release(int stream) {
    assert(stream >= 0 && static_cast<size_t>(stream) < max_streams_);
    pending_.erase(stream);
    release_stream(stream);
  }

  bool get_pending_and_release(int stream, T& output) {
    typename google::sparse_hash_map<int, T>::iterator i = pending_.find(stream);
    if (i != pending_.end()) {
      output = i->second;
      pending_.erase(i);
      release_stream(stream);
      return true;
    }
    return false;
  }

  size_t available_streams() const { return max_streams_ - pending_.size(); }
  size_t pending_streams() const { return pending_.size(); }
  size_t max_streams() const { return max_streams_; }

private:
#if defined(_MSC_VER) && defined(_M_AMD64)
  typedef __int64 word_t;
#else
  typedef unsigned long word_t;
#endif

  static const size_t NUM_BITS_PER_WORD = sizeof(word_t) * 8;

  static inline int num_bytes_for_stream(int protocol_version) {
    if (protocol_version >= 3) {
      return 2;
    } else {
      return 1;
    }
  }

  static inline int count_trailing_zeros(word_t word) {
#if defined(__GNUC__)
    return __builtin_ctzl(word);
#elif defined(_MSC_VER)
    unsigned long index;
#  if defined(_M_AMD64)
    assert(_BitScanForward64(&index, word) != 0);
#  else
    assert(_BitScanForward(&index, word) != 0);
#  endif
    return static_cast<int>(index);
#else
#endif
  }

private:
  int acquire_stream() {
    const size_t offset = offset_;
    const size_t num_words = num_words_;

    ++offset_;

    for (size_t i = 0; i < num_words; ++i) {
      size_t index = (i + offset) % num_words;
      int stream = get_and_set_first_available_stream(index);
      if (stream >= 0) return stream + (NUM_BITS_PER_WORD * index);
    }

    return -1;
  }

  inline void release_stream(int stream) {
    assert((words_[stream / NUM_BITS_PER_WORD] & (1L << (stream % NUM_BITS_PER_WORD))) == 0);
    words_[stream / NUM_BITS_PER_WORD] |=
        (static_cast<word_t>(1) << (stream % NUM_BITS_PER_WORD));
  }

  inline int get_and_set_first_available_stream(size_t index) {
    word_t word = words_[index];
    if (word == 0) return -1;
    int stream = count_trailing_zeros(word);
    words_[index] ^= (static_cast<word_t>(1) << stream);
    return stream;
  }

private:
  const size_t max_streams_;
  const size_t num_words_;
  size_t offset_;
  ScopedPtr<word_t[]> words_;
  google::sparse_hash_map<int, T> pending_;
};

} // namespace cass

#endif
<commit_msg>Moved to using dense hash map<commit_after>/*
  Copyright (c) 2014-2015 DataStax

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

#ifndef __CASS_STREAM_MANAGER_HPP_INCLUDED__
#define __CASS_STREAM_MANAGER_HPP_INCLUDED__

#include "macros.hpp"
#include "scoped_ptr.hpp"

#include <assert.h>
#include <stdint.h>
#include <string.h>

#include <google/dense_hash_map>

#if defined(_MSC_VER)
#include <intrin.h>
#endif

namespace cass {

template <class T>
class StreamManager {
public:
  StreamManager(int protocol_version)
      : max_streams_(1 << (num_bytes_for_stream(protocol_version) * 8 - 1))
      , num_words_(max_streams_ / NUM_BITS_PER_WORD)
      , offset_(0)
      , words_(new word_t[num_words_]) {
    pending_.set_empty_key(-1);
    pending_.set_deleted_key(-2);
    pending_.min_load_factor(0.0);
    memset(words_.get(), 0xFF, sizeof(word_t) * num_words_);
  }

  int acquire(const T& item) {
    int stream = acquire_stream();
    if (stream < 0) return -1;
    pending_[stream] = item;
    return stream;
  }

  void release(int stream) {
    assert(stream >= 0 && static_cast<size_t>(stream) < max_streams_);
    pending_.erase(stream);
    release_stream(stream);
  }

  bool get_pending_and_release(int stream, T& output) {
    typename google::dense_hash_map<int, T>::iterator i = pending_.find(stream);
    if (i != pending_.end()) {
      output = i->second;
      pending_.erase(i);
      release_stream(stream);
      return true;
    }
    return false;
  }

  size_t available_streams() const { return max_streams_ - pending_.size(); }
  size_t pending_streams() const { return pending_.size(); }
  size_t max_streams() const { return max_streams_; }

private:
#if defined(_MSC_VER) && defined(_M_AMD64)
  typedef __int64 word_t;
#else
  typedef unsigned long word_t;
#endif

  static const size_t NUM_BITS_PER_WORD = sizeof(word_t) * 8;

  static inline int num_bytes_for_stream(int protocol_version) {
    if (protocol_version >= 3) {
      return 2;
    } else {
      return 1;
    }
  }

  static inline int count_trailing_zeros(word_t word) {
#if defined(__GNUC__)
    return __builtin_ctzl(word);
#elif defined(_MSC_VER)
    unsigned long index;
#  if defined(_M_AMD64)
    assert(_BitScanForward64(&index, word) != 0);
#  else
    assert(_BitScanForward(&index, word) != 0);
#  endif
    return static_cast<int>(index);
#else
#endif
  }

private:
  int acquire_stream() {
    const size_t offset = offset_;
    const size_t num_words = num_words_;

    ++offset_;

    for (size_t i = 0; i < num_words; ++i) {
      size_t index = (i + offset) % num_words;
      int stream = get_and_set_first_available_stream(index);
      if (stream >= 0) return stream + (NUM_BITS_PER_WORD * index);
    }

    return -1;
  }

  inline void release_stream(int stream) {
    assert((words_[stream / NUM_BITS_PER_WORD] & (1L << (stream % NUM_BITS_PER_WORD))) == 0);
    words_[stream / NUM_BITS_PER_WORD] |=
        (static_cast<word_t>(1) << (stream % NUM_BITS_PER_WORD));
  }

  inline int get_and_set_first_available_stream(size_t index) {
    word_t word = words_[index];
    if (word == 0) return -1;
    int stream = count_trailing_zeros(word);
    words_[index] ^= (static_cast<word_t>(1) << stream);
    return stream;
  }

private:
  const size_t max_streams_;
  const size_t num_words_;
  size_t offset_;
  ScopedPtr<word_t[]> words_;
  google::dense_hash_map<int, T> pending_;

private:
  DISALLOW_COPY_AND_ASSIGN(StreamManager);
};

} // namespace cass

#endif
<|endoftext|>


<commit_before>///
/// @file  PhiTiny.cpp
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include "PhiTiny.hpp"

#include <stdint.h>
#include <vector>
#include <cassert>
#include <cstddef>

namespace {

/// Thread-safe singleton without locking
/// @note Meyer's singleton (static const Singleton instance) causes a
///       race condition with MSVC 2013 and OpenMP
///
const primecount::PhiTiny phiTiny;

}

namespace primecount {

int64_t phi_tiny(int64_t x, int64_t a)
{
  return phiTiny.phi(x, a);
}

const int64_t PhiTiny::MAX_A = 6;

const int32_t PhiTiny::primes_[7] = { 0, 2, 3, 5, 7, 11, 13 };

/// prime_products_[n] = \prod_{i=1}^{n} primes_[i]
const int32_t PhiTiny::prime_products_[7] = { 1, 2, 6, 30, 210, 2310, 30030 };

/// totients_[n] = \prod_{i=1}^{n} (primes_[i] - 1)
const int32_t PhiTiny::totients_[7] = { 1, 1, 2, 8, 48, 480, 5760 };

PhiTiny::PhiTiny()
{
  phi_cache_[0].push_back(0);

  // Initialize the phi_cache_ lookup tables
  for (int a = 1; a <= MAX_A; a++)
  {
    std::size_t size = prime_products_[a];
    phi_cache_[a].reserve(size);

    for (int x = 0; x < size; x++)
    {
      int16_t phixa = static_cast<int16_t>(phi(x, a - 1) - phi(x / primes_[a], a - 1));
      phi_cache_[a].push_back(phixa);
    }
  }
}

/// Partial sieve function (a.k.a. Legendre-sum).
/// phi(x, a) counts the numbers <= x that are not divisible
/// by any of the first a primes.
/// @pre is_cached(a) == true.
///
int64_t PhiTiny::phi(int64_t x, int64_t a) const
{
  assert(x >= 0);
  assert(a <= MAX_A);
  return (x / prime_products_[a]) * totients_[a] + phi_cache_[a][x % prime_products_[a]];
}

} // namespace primecount
<commit_msg>Silence warning<commit_after>///
/// @file  PhiTiny.cpp
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include "PhiTiny.hpp"

#include <stdint.h>
#include <vector>
#include <cassert>

namespace {

/// Thread-safe singleton without locking
/// @note Meyer's singleton (static const Singleton instance) causes a
///       race condition with MSVC 2013 and OpenMP
///
const primecount::PhiTiny phiTiny;

}

namespace primecount {

int64_t phi_tiny(int64_t x, int64_t a)
{
  return phiTiny.phi(x, a);
}

const int64_t PhiTiny::MAX_A = 6;

const int32_t PhiTiny::primes_[7] = { 0, 2, 3, 5, 7, 11, 13 };

/// prime_products_[n] = \prod_{i=1}^{n} primes_[i]
const int32_t PhiTiny::prime_products_[7] = { 1, 2, 6, 30, 210, 2310, 30030 };

/// totients_[n] = \prod_{i=1}^{n} (primes_[i] - 1)
const int32_t PhiTiny::totients_[7] = { 1, 1, 2, 8, 48, 480, 5760 };

PhiTiny::PhiTiny()
{
  phi_cache_[0].push_back(0);

  // Initialize the phi_cache_ lookup tables
  for (int a = 1; a <= MAX_A; a++)
  {
    int size = prime_products_[a];
    std::vector<int16_t>& cache = phi_cache_[a];
    cache.reserve(size);

    for (int x = 0; x < size; x++)
    {
      int16_t phixa = static_cast<int16_t>(phi(x, a - 1) - phi(x / primes_[a], a - 1));
      cache.push_back(phixa);
    }
  }
}

/// Partial sieve function (a.k.a. Legendre-sum).
/// phi(x, a) counts the numbers <= x that are not divisible
/// by any of the first a primes.
/// @pre is_cached(a) == true.
///
int64_t PhiTiny::phi(int64_t x, int64_t a) const
{
  assert(x >= 0);
  assert(a <= MAX_A);
  return (x / prime_products_[a]) * totients_[a] + phi_cache_[a][x % prime_products_[a]];
}

} // namespace primecount
<|endoftext|>


<commit_before>// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
#ifndef IOX_UTILS_CXX_HELPLETS_HPP
#define IOX_UTILS_CXX_HELPLETS_HPP

#include "iceoryx_utils/cxx/generic_raii.hpp"
#include "iceoryx_utils/platform/platform_correction.hpp"

#include <assert.h>
#include <iostream>
#include <limits>
#include <type_traits>

namespace iox
{
namespace cxx
{
namespace internal
{
inline void
Require(const bool condition, const char* file, const int line, const char* function, const char* conditionString)
{
    if (!condition)
    {
        std::cerr << "Condition: " << conditionString << " in " << function << " is violated. (" << file << ":" << line
                  << ")" << std::endl;
        std::terminate();
    }
}

/// @brief struct to find the best fitting unsigned integer type
template <bool GreaterUint8, bool GreaterUint16, bool GreaterUint32>
struct bestFittingTypeImpl
{
    using Type_t = uint64_t;
};

template <>
struct bestFittingTypeImpl<false, false, false>
{
    using Type_t = uint8_t;
};

template <>
struct bestFittingTypeImpl<true, false, false>
{
    using Type_t = uint16_t;
};

template <>
struct bestFittingTypeImpl<true, true, false>
{
    using Type_t = uint32_t;
};
} // namespace internal

// implementing C++ Core Guideline, I.6. Prefer Expects
// see:
// https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Ri-expects
#define Expects(condition) internal::Require(condition, __FILE__, __LINE__, __PRETTY_FUNCTION__, #condition)

// implementing C++ Core Guideline, I.8. Prefer Ensures
// see:
// https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Ri-ensures
#define Ensures(condition) internal::Require(condition, __FILE__, __LINE__, __PRETTY_FUNCTION__, #condition)

template <typename T, typename = typename std::enable_if<std::is_pointer<T>::value, void>::type>
struct not_null
{
  public:
    not_null(T t)
        : value(t)
    {
        Expects(t != nullptr);
    }

    constexpr operator T() const
    {
        return value;
    }

  private:
    T value;
};

template <typename T, T Minimum>
struct greater_or_equal
{
  public:
    greater_or_equal(T t)
        : value(t)
    {
        Expects(t >= Minimum);
    }

    constexpr operator T() const
    {
        return value;
    }

  private:
    T value;
};

template <typename T, T Minimum, T Maximum>
struct range
{
  public:
    range(T t)
        : value(t)
    {
        Expects(t >= Minimum && t <= Maximum);
    }

    constexpr operator T() const
    {
        return value;
    }

  private:
    T value;
};

template <typename T>
T align(const T value, const T alignment)
{
    T remainder = value % alignment;
    return value + ((remainder == 0u) ? 0u : alignment - remainder);
}

/// @brief allocates aligned memory which can only be free'd by alignedFree
/// @param[in] alignment, alignment of the memory
/// @param[in] size, memory size
/// @return void pointer to the aligned memory
void* alignedAlloc(const uint64_t alignment, const uint64_t size) noexcept;

/// @brief frees aligned memory allocated with alignedAlloc
/// @param[in] memory, pointer to the aligned memory
void alignedFree(void* const memory);

/// template recursion stopper for maximum alignment calculation
template <size_t s = 0>
constexpr size_t maxAlignment()
{
    return s;
}

/// calculate maximum alignment of supplied types
template <typename T, typename... Args>
constexpr size_t maxAlignment()
{
    return alignof(T) > maxAlignment<Args...>() ? alignof(T) : maxAlignment<Args...>();
}

/// template recursion stopper for maximum size calculation
template <size_t s = 0>
constexpr size_t maxSize()
{
    return s;
}

/// calculate maximum size of supplied types
template <typename T, typename... Args>
constexpr size_t maxSize()
{
    return sizeof(T) > maxSize<Args...>() ? sizeof(T) : maxSize<Args...>();
}

/// @todo better name
/// create a GenericRAII object to cleanup a static optional object at the end of the scope
/// @param [in] T memory container which has emplace(...) and reset
/// @param [in] CTorArgs ctor types for the object to construct
/// @param [in] memory is a reference to a memory container, e.g. cxx::optional
/// @param [in] ctorArgs ctor arguments for the object to construct
/// @return cxx::GenericRAII
template <typename T, typename... CTorArgs>
GenericRAII makeScopedStatic(T& memory, CTorArgs&&... ctorArgs)
{
    memory.emplace(std::forward<CTorArgs>(ctorArgs)...);
    return GenericRAII([] {}, [&memory] { memory.reset(); });
}
/// Convert Enum class type to string
template <typename T, typename Enumeration>
const char* convertEnumToString(T port, const Enumeration source)
{
    return port[static_cast<size_t>(source)];
}

/// cast an enum to its underlying type
template <typename enum_type>
auto enumTypeAsUnderlyingType(enum_type const value) -> typename std::underlying_type<enum_type>::type
{
    return static_cast<typename std::underlying_type<enum_type>::type>(value);
}

/// calls a given functor for every element in a given container
/// @tparam[in] Container type which must be iteratable
/// @tparam[in] Functor which has one argument, the element type of the container
/// @param[in] c container which should be iterated
/// @param[in] f functor which should be applied to every element
template <typename Container, typename Functor>
void forEach(Container& c, const Functor& f) noexcept
{
    for (auto& element : c)
    {
        f(element);
    }
}

/// @brief Get the size of a string represented by a char array at compile time.
/// @tparam The size of the char array filled out by the compiler.
/// @param[in] The actual content of the char array is not of interest. Its just the size of the array that matters.
/// @return Returns the size of a char array at compile time.
template <uint64_t SizeValue>
static constexpr uint64_t strlen2(char const (&/*notInterested*/)[SizeValue])
{
    return SizeValue - 1;
}

/// @brief get the best fitting unsigned integer type for a given value at compile time
template <uint64_t Value>
struct bestFittingType
{
    using Type_t = typename internal::bestFittingTypeImpl<(Value > std::numeric_limits<uint8_t>::max()),
                                                          (Value > std::numeric_limits<uint16_t>::max()),
                                                          (Value > std::numeric_limits<uint32_t>::max())>::Type_t;
};

template <uint64_t Value>
using BestFittingType_t = typename bestFittingType<Value>::Type_t;

/// @brief if a function has a return value which you do not want to use then you can wrap the function with that macro.
/// Purpose is to suppress the unused compiler warning by adding an attribute to the return value
/// @param[in] name name of the function where the return value is not used.
/// @code
///     uint32_t foo();
///     DISCARD_RESULT(foo()); // suppress compiler warning for unused return value
/// @endcode
// clang-format off
#define DISCARD_RESULT_VARIABLE_GENERATOR(name, suffix) name ## _ ## suffix
#define DISCARD_RESULT_VARIABLE(name, suffix) DISCARD_RESULT_VARIABLE_GENERATOR(name, suffix)
#define DISCARD_RESULT(expr) auto DISCARD_RESULT_VARIABLE(unusedOnLine, __LINE__) [[gnu::unused]] = expr
// clang-format on

} // namespace cxx
} // namespace iox

#endif // IOX_UTILS_CXX_HELPLETS_HPP
<commit_msg>iox-#350 ignore warnings for comparisons in bestFittingType implementation<commit_after>// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
#ifndef IOX_UTILS_CXX_HELPLETS_HPP
#define IOX_UTILS_CXX_HELPLETS_HPP

#include "iceoryx_utils/cxx/generic_raii.hpp"
#include "iceoryx_utils/platform/platform_correction.hpp"

#include <assert.h>
#include <iostream>
#include <limits>
#include <type_traits>

namespace iox
{
namespace cxx
{
namespace internal
{
inline void
Require(const bool condition, const char* file, const int line, const char* function, const char* conditionString)
{
    if (!condition)
    {
        std::cerr << "Condition: " << conditionString << " in " << function << " is violated. (" << file << ":" << line
                  << ")" << std::endl;
        std::terminate();
    }
}

/// @brief struct to find the best fitting unsigned integer type
template <bool GreaterUint8, bool GreaterUint16, bool GreaterUint32>
struct bestFittingTypeImpl
{
    using Type_t = uint64_t;
};

template <>
struct bestFittingTypeImpl<false, false, false>
{
    using Type_t = uint8_t;
};

template <>
struct bestFittingTypeImpl<true, false, false>
{
    using Type_t = uint16_t;
};

template <>
struct bestFittingTypeImpl<true, true, false>
{
    using Type_t = uint32_t;
};
} // namespace internal

// implementing C++ Core Guideline, I.6. Prefer Expects
// see:
// https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Ri-expects
#define Expects(condition) internal::Require(condition, __FILE__, __LINE__, __PRETTY_FUNCTION__, #condition)

// implementing C++ Core Guideline, I.8. Prefer Ensures
// see:
// https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Ri-ensures
#define Ensures(condition) internal::Require(condition, __FILE__, __LINE__, __PRETTY_FUNCTION__, #condition)

template <typename T, typename = typename std::enable_if<std::is_pointer<T>::value, void>::type>
struct not_null
{
  public:
    not_null(T t)
        : value(t)
    {
        Expects(t != nullptr);
    }

    constexpr operator T() const
    {
        return value;
    }

  private:
    T value;
};

template <typename T, T Minimum>
struct greater_or_equal
{
  public:
    greater_or_equal(T t)
        : value(t)
    {
        Expects(t >= Minimum);
    }

    constexpr operator T() const
    {
        return value;
    }

  private:
    T value;
};

template <typename T, T Minimum, T Maximum>
struct range
{
  public:
    range(T t)
        : value(t)
    {
        Expects(t >= Minimum && t <= Maximum);
    }

    constexpr operator T() const
    {
        return value;
    }

  private:
    T value;
};

template <typename T>
T align(const T value, const T alignment)
{
    T remainder = value % alignment;
    return value + ((remainder == 0u) ? 0u : alignment - remainder);
}

/// @brief allocates aligned memory which can only be free'd by alignedFree
/// @param[in] alignment, alignment of the memory
/// @param[in] size, memory size
/// @return void pointer to the aligned memory
void* alignedAlloc(const uint64_t alignment, const uint64_t size) noexcept;

/// @brief frees aligned memory allocated with alignedAlloc
/// @param[in] memory, pointer to the aligned memory
void alignedFree(void* const memory);

/// template recursion stopper for maximum alignment calculation
template <size_t s = 0>
constexpr size_t maxAlignment()
{
    return s;
}

/// calculate maximum alignment of supplied types
template <typename T, typename... Args>
constexpr size_t maxAlignment()
{
    return alignof(T) > maxAlignment<Args...>() ? alignof(T) : maxAlignment<Args...>();
}

/// template recursion stopper for maximum size calculation
template <size_t s = 0>
constexpr size_t maxSize()
{
    return s;
}

/// calculate maximum size of supplied types
template <typename T, typename... Args>
constexpr size_t maxSize()
{
    return sizeof(T) > maxSize<Args...>() ? sizeof(T) : maxSize<Args...>();
}

/// @todo better name
/// create a GenericRAII object to cleanup a static optional object at the end of the scope
/// @param [in] T memory container which has emplace(...) and reset
/// @param [in] CTorArgs ctor types for the object to construct
/// @param [in] memory is a reference to a memory container, e.g. cxx::optional
/// @param [in] ctorArgs ctor arguments for the object to construct
/// @return cxx::GenericRAII
template <typename T, typename... CTorArgs>
GenericRAII makeScopedStatic(T& memory, CTorArgs&&... ctorArgs)
{
    memory.emplace(std::forward<CTorArgs>(ctorArgs)...);
    return GenericRAII([] {}, [&memory] { memory.reset(); });
}
/// Convert Enum class type to string
template <typename T, typename Enumeration>
const char* convertEnumToString(T port, const Enumeration source)
{
    return port[static_cast<size_t>(source)];
}

/// cast an enum to its underlying type
template <typename enum_type>
auto enumTypeAsUnderlyingType(enum_type const value) -> typename std::underlying_type<enum_type>::type
{
    return static_cast<typename std::underlying_type<enum_type>::type>(value);
}

/// calls a given functor for every element in a given container
/// @tparam[in] Container type which must be iteratable
/// @tparam[in] Functor which has one argument, the element type of the container
/// @param[in] c container which should be iterated
/// @param[in] f functor which should be applied to every element
template <typename Container, typename Functor>
void forEach(Container& c, const Functor& f) noexcept
{
    for (auto& element : c)
    {
        f(element);
    }
}

/// @brief Get the size of a string represented by a char array at compile time.
/// @tparam The size of the char array filled out by the compiler.
/// @param[in] The actual content of the char array is not of interest. Its just the size of the array that matters.
/// @return Returns the size of a char array at compile time.
template <uint64_t SizeValue>
static constexpr uint64_t strlen2(char const (&/*notInterested*/)[SizeValue])
{
    return SizeValue - 1;
}

/// @brief get the best fitting unsigned integer type for a given value at compile time
template <uint64_t Value>
struct bestFittingType
{
/// ignore the warnings because we need the comparisons to find the best fitting type
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"
    using Type_t = typename internal::bestFittingTypeImpl<(Value > std::numeric_limits<uint8_t>::max()),
                                                          (Value > std::numeric_limits<uint16_t>::max()),
                                                          (Value > std::numeric_limits<uint32_t>::max())>::Type_t;
#pragma GCC diagnostic pop
};

template <uint64_t Value>
using BestFittingType_t = typename bestFittingType<Value>::Type_t;

/// @brief if a function has a return value which you do not want to use then you can wrap the function with that macro.
/// Purpose is to suppress the unused compiler warning by adding an attribute to the return value
/// @param[in] name name of the function where the return value is not used.
/// @code
///     uint32_t foo();
///     DISCARD_RESULT(foo()); // suppress compiler warning for unused return value
/// @endcode
// clang-format off
#define DISCARD_RESULT_VARIABLE_GENERATOR(name, suffix) name ## _ ## suffix
#define DISCARD_RESULT_VARIABLE(name, suffix) DISCARD_RESULT_VARIABLE_GENERATOR(name, suffix)
#define DISCARD_RESULT(expr) auto DISCARD_RESULT_VARIABLE(unusedOnLine, __LINE__) [[gnu::unused]] = expr
// clang-format on

} // namespace cxx
} // namespace iox

#endif // IOX_UTILS_CXX_HELPLETS_HPP
<|endoftext|>


<commit_before>#include	"parallel-hashmap/parallel_hashmap/phmap.h"
#include	"smhasher/meow_hash_x64_aesni.h"
#include	"wyhash/wyhash.h"
#include	"xxHash/xxhash.c"
#include	"t1ha/t1ha.h"
#include	<sys/time.h>
#include	<iostream>
#include	<fstream>
#include	<sstream>
#include	<vector>
using	namespace	std;
//struct	hasher{	size_t	operator()(const	string	&s)const{	return	wyhash(s.c_str(),s.size(),34432,_wyp);	}};
//struct	full_hasher{	size_t	operator()(void	*p,	uint64_t	len,	uint64_t	seed)const{	return	wyhash(p,len,seed,_wyp);	}};

struct	hasher{	size_t	operator()(const	string	&s)const{	return	XXH3_64bits_withSeed(s.c_str(),s.size(),34432);	}};
struct	full_hasher{	size_t	operator()(void	*p,	uint64_t	len,	uint64_t	seed)const{	return	XXH3_64bits_withSeed(p,len,seed);	}};

uint64_t	bench_hash(vector<string>	&v,	string	name){
	hasher	h;	full_hasher	f;
	timeval	beg,	end;	uint64_t	dummy=0,	N=v.size(),	R=0x10000000ull/N;
	cout.precision(2);	cout.setf(ios::fixed);	cout<<name<<(name.size()<8?"\t\t":"\t");
	for(size_t  i=0;    i<N;    i++)    dummy+=h(v[i]);
	gettimeofday(&beg,NULL);
	for(size_t  r=0;    r<R;    r++)	for(size_t	i=0;	i<N;	i++)	dummy+=h(v[i]);
	gettimeofday(&end,NULL);
	cout<<1e-6*R*N/(end.tv_sec-beg.tv_sec+1e-6*(end.tv_usec-beg.tv_usec))<<"\t";
	phmap::flat_hash_map<string,unsigned,hasher>	ma;
	for(size_t	i=0;	i<N;	i++)	ma[v[i]]++;
	gettimeofday(&beg,NULL);
	for(size_t  r=0;    r<R;    r++)	for(size_t	i=0;	i<N;	i++)	dummy+=ma[v[i]]++;
	gettimeofday(&end,NULL);
	cout<<1e-6*R*N/(end.tv_sec-beg.tv_sec+1e-6*(end.tv_usec-beg.tv_usec))<<"\t";
	char	temp[128];
	gettimeofday(&beg,NULL);
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Modify here !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	for(size_t  r=0;    r<R;    r++)	for(size_t	i=0;	i<N;	i++){	dummy+=f(temp,(dummy&31)+1,i);	(*temp)++;	}
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	gettimeofday(&end,NULL);
	cout<<1e-6*R*N/(end.tv_sec-beg.tv_sec+1e-6*(end.tv_usec-beg.tv_usec))<<"\t";
	string	s;
	s.resize(1024);	dummy+=h(s);
	gettimeofday(&beg,NULL);
	for(size_t	r=0;	r<(1ull<<26);	r++){	dummy+=h(s);	s[0]++;	}
	gettimeofday(&end,NULL);
	cout<<1e-9*(1ull<<26)*s.size()/(end.tv_sec-beg.tv_sec+1e-6*(end.tv_usec-beg.tv_usec))<<"\t";
	s.resize(0x40000ull);	dummy+=h(s);
	gettimeofday(&beg,NULL);
	for(size_t	r=0;	r<(1ull<<20);	r++){	dummy+=h(s);	s[0]++;	}
	gettimeofday(&end,NULL);
	cout<<1e-9*(1ull<<20)*s.size()/(end.tv_sec-beg.tv_sec+1e-6*(end.tv_usec-beg.tv_usec))<<"\t";
	s.resize(0x1000000ull);	dummy+=h(s);
	gettimeofday(&beg,NULL);
	for(size_t	r=0;	r<4096;	r++){	dummy+=h(s);	s[0]++;	}
	gettimeofday(&end,NULL);
	cout<<1e-9*4096*s.size()/(end.tv_sec-beg.tv_sec+1e-6*(end.tv_usec-beg.tv_usec))<<"\t";
	s.resize(0x40000000ull);	dummy+=h(s);
	gettimeofday(&beg,NULL);
	for(size_t	r=0;	r<64;	r++){	dummy+=h(s);	s[0]++;	}
	gettimeofday(&end,NULL);
	cout<<1e-9*64*s.size()/(end.tv_sec-beg.tv_sec+1e-6*(end.tv_usec-beg.tv_usec))<<"\n";
	return	dummy;
}

int	main(int	ac,	char	**av){
	string	file="/usr/share/dict/words";
	if(ac>1)	file=av[1];
	vector<string>	v;	string	s;
	ifstream	fi(file.c_str());
	for(fi>>s;	!fi.eof();	fi>>s)	if(s.size())	v.push_back(s);
	fi.close();
	uint64_t	r=0;
	cout<<"Benchmarking\t"<<file<<'\n';
	cout<<"HashFunction\tWords\tHashmap\tRand32\t1K\t256K\t16M\t1G\n";
	r+=bench_hash(v,"");
	return	r;
}
<commit_msg>Delete benchhash.cpp<commit_after><|endoftext|>