<commit_before>#include <clang-c/Index.h>
#include <cstdio>

#include <iostream>
#include <vector>

namespace {
    const unsigned int indent_spaces = 4;
}

CXCursor tu_cursor;

struct client_data
{
    CXTranslationUnit tu;
    std::vector<CXCursor> current_namespaces;
    CXCursor current_struct;
};

std::pair<CXToken*, unsigned int>
get_tokens (CXTranslationUnit tu, CXCursor cursor)
{
    CXSourceRange range = clang_getCursorExtent(cursor);
    CXSourceLocation start = clang_getRangeStart(range);
    CXSourceLocation end = clang_getRangeEnd(range);
    unsigned int start_offset, end_offset;

    std::pair<CXToken*, unsigned int> retval(0, 0);
    clang_tokenize(tu, range, &retval.first, &retval.second);

    return retval;
}

void
free_tokens (CXTranslationUnit tu, std::pair<CXToken*, unsigned int> tokens)
{ clang_disposeTokens(tu, tokens.first, tokens.second); }

void print_tokens (CXTranslationUnit tu, CXCursor cursor)
{
    std::pair<CXToken*, unsigned int> tokens = get_tokens(tu, cursor);

    for (unsigned int i = 0; i < tokens.second; ++i) {
        if (i)
            std::cout << " ";
        CXString spelling = clang_getTokenSpelling(tu, tokens.first[i]);
        std::cout << clang_getCString(spelling);
    }
    std::cout << "\n";

    free_tokens(tu, tokens);
}

bool struct_kind (CXCursorKind kind)
{
    switch (kind) {
    case CXCursor_ClassDecl:
    case CXCursor_StructDecl:
    case CXCursor_ClassTemplate:
    case CXCursor_ClassTemplatePartialSpecialization:
        return true;
    }
    return false;
}

std::string indent (const client_data& data)
{
    std::size_t size = data.current_namespaces.size();
    return std::string(size * indent_spaces, ' ');
}

void print (const client_data& data, const char** lines, std::size_t num_lines)
{
    std::string padding(indent_spaces, ' ');
    for (unsigned int i = 0; i < num_lines; ++i) {
        if (lines[i])
            std::cout << indent(data) << padding << lines[i] << "\n";
        else
            std::cout << "\n";
    }
}

void open_struct (const client_data& data, CXCursor struct_cursor)
{
    std::pair<CXToken*, unsigned int> tokens =
        get_tokens(data.tu, struct_cursor);

    std::cout << "\n" << indent(data);

    const std::string open_brace = "{";
    const std::string struct_ = "struct";
    const std::string class_ = "class";

    for (unsigned int i = 0; i < tokens.second; ++i) {
        CXString spelling = clang_getTokenSpelling(data.tu, tokens.first[i]);

        const char* c_str = clang_getCString(spelling);

        if (c_str == open_brace)
            break;

        if (c_str == struct_ || c_str == class_) {
            std::cout << "\n" << indent(data);
        } else if (i) {
            std::cout << " ";
        }

        std::cout << c_str;
    }

    free_tokens(data.tu, tokens);

    std::cout << "\n"
              << indent(data) << "{\n"
              << indent(data) << "public:\n";

    const char* public_interface[] = {
        0,
        "any_printable () = default;",
        0,
        "template <typename T_T__>",
        "any_printable (T_T__ value) :",
        "    handle_ (",
        "        std::make_shared<",
        "            handle<typename std::remove_reference<T_T__>::type>",
        "        >(std::forward<T_T__>(value))",
        "    )",
        "{}",
        0,
        "any_printable (any_printable && rhs) noexcept = default;",
        0,
        "template <typename T_T__>",
        "any_printable & operator= (T_T__ value)",
        "{",
        "    if (handle_.unique())",
        "        *handle_ = std::forward<T_T__>(value);",
        "    else if (!handle_)",
        "        handle_ = std::make_shared<T_T__>(std::forward<T_T__>(value));",
        "    return *this;",
        "}",
        0,
        "any_printable & operator= (any_printable && rhs) noexcept = default;"
    };

    print(data,
          public_interface,
          sizeof(public_interface) / sizeof(const char*));
}

void close_struct (const client_data& data)
{
    std::cout << "\n"
              << indent(data) << "private:\n";

    const char* handle_base_preamble[] = {
        0,
        "struct handle_base",
        "{",
        "    virtual ~handle_base () {}",
        "    virtual std::shared_ptr<handle_base> close () const = 0;",
        0
    };

    print(data,
          handle_base_preamble,
          sizeof(handle_base_preamble) / sizeof(const char*));

    // TODO: pure virtual

    const char* handle_preamble[] = {
        "};",
        0,
        "template <typename T_T__>",
        "struct handle :",
        "    handle_base",
        "{",
        "    template <typename T_T__>",
        "    handle (T_T__ value,",
        "            typename std::enable_if<",
        "                std::is_reference<U_U__>::value",
        "            >::type* = 0) :",
        "        value_ (value)",
        "    {}",
        0,
        "    template <typename U_U__ = T_T__>",
        "    handle (T_T__ value,",
        "            typename std::enable_if<",
        "                !std::is_reference<U_U__>::value,",
        "                int",
        "            >::type* = 0) noexcept :",
        "        value_ (std::move(value))",
        "    {}",
        0,
        "    virtual std::shared_ptr<handle_base> clone () const",
        "    { return std::make_shared<handle>(value_); }"
    };

    print(data,
          handle_preamble,
          sizeof(handle_preamble) / sizeof(const char*));

    // TODO: virtual implementations

    const char* handle_postamble[] = {
        0,
        "    T_T__ value_;",
        "};",
        0,
        "template <typename T_T__>",
        "struct handle<std::reference_wrapper<T_T__>> :",
        "    handle<T_T__ &>",
        "{",
        "    handle (std::reference_wrapper<T_T__> ref) :",
        "        handle<T_T__ &> (ref.get())",
        "    {}",
        "};",
        0,
        "const handle_base & read () const",
        "{ return *handle_; }",
        0,
        "handle_base & write ()",
        "{",
        "    if (!handle_.unique())",
        "        handle_ = handle_->clone();",
        "    return *handle_;",
        "}",
        0,
        "std::shared_ptr<handle_base> handle_;"
    };

    print(data,
          handle_postamble,
          sizeof(handle_postamble) / sizeof(const char*));

    std::cout << "\n"
              << indent(data) << "};\n";
}

void print_member_function(const client_data& data, CXCursor cursor)
{
    std::pair<CXToken*, unsigned int> tokens = get_tokens(data.tu, cursor);

    std::cout << "\n"
              << std::string(indent_spaces, ' ') << indent(data);

    const std::string open_brace = "{";
    const std::string semicolon = ";";

    for (unsigned int i = 0; i < tokens.second; ++i) {
        CXString spelling = clang_getTokenSpelling(data.tu, tokens.first[i]);

        const char* c_str = clang_getCString(spelling);

        if (c_str == open_brace || c_str == semicolon)
            break;

        if (i)
            std::cout << " ";

        std::cout << c_str;
    }

    free_tokens(data.tu, tokens);

    const char* return_str =
        clang_getCursorResultType(cursor).kind == CXType_Void ? "" : "return ";

    std::cout << "\n" << std::string(indent_spaces, ' ') << indent(data)
              << "{ assert(handle_); " << return_str << "handle_->"
              << clang_getCString(clang_getCursorSpelling(cursor))
              << "( ";
    const int args = clang_Cursor_getNumArguments(cursor);
    for (int i = 0; i < args; ++i) {
        if (i)
            std::cout << ", ";
        CXCursor arg_cursor = clang_Cursor_getArgument(cursor, i);
        std::cout << clang_getCString(clang_getCursorSpelling(arg_cursor));
    }
    std::cout << " ); }\n";
}

void open_namespace (const client_data& data, CXCursor namespace_)
{
    std::cout
        << "\n"
        << indent(data)
        << "namespace "
        << clang_getCString(clang_getCursorSpelling(namespace_))
        << " {";
}

void close_namespace (const client_data& data)
{ std::cout << "\n" << indent(data) << "}\n"; }

void dump_cursor (const char* name, CXCursor cursor)
{
    CXCursorKind kind = clang_getCursorKind(cursor);
    CXString kind_spelling = clang_getCursorKindSpelling(kind);
    CXString cursor_spelling = clang_getCursorSpelling(cursor);
    std::cout << name << " "
              << clang_getCString(kind_spelling) << " "
              << clang_getCString(cursor_spelling) << " "
              << "\n";
}

CXChildVisitResult
visitor (CXCursor cursor, CXCursor parent, CXClientData data_)
{
    client_data& data = *static_cast<client_data*>(data_);

#if 0
    std::cout << "\n";
    dump_cursor("cursor", cursor);
    dump_cursor("parent", parent);
#endif

    CXCursor null_cursor = clang_getNullCursor();

    // close open namespaces we have left
    CXCursor enclosing_namespace = parent;
    while (!clang_equalCursors(enclosing_namespace, tu_cursor) &&
           clang_getCursorKind(enclosing_namespace) != CXCursor_Namespace) {
        enclosing_namespace =
            clang_getCursorSemanticParent(enclosing_namespace);
    }
#if 0
    dump_cursor("enclosing_namespace", enclosing_namespace);
#endif
    if (!clang_equalCursors(enclosing_namespace, tu_cursor) &&
        clang_getCursorKind(enclosing_namespace) == CXCursor_Namespace) {
        while (!clang_equalCursors(enclosing_namespace,
                                   data.current_namespaces.back())) {
            data.current_namespaces.pop_back();
            close_namespace(data);
        }
    }

    // close open struct if we have left it
    CXCursor enclosing_struct = parent;
    while (!clang_equalCursors(enclosing_struct, tu_cursor) &&
           !struct_kind(clang_getCursorKind(enclosing_struct))) {
        enclosing_struct = clang_getCursorSemanticParent(enclosing_struct);
    }
#if 0
    dump_cursor("enclosing_struct", enclosing_struct);
#endif
    if (!clang_Cursor_isNull(data.current_struct) &&
        !clang_equalCursors(enclosing_struct, data.current_struct)) {
        data.current_struct = null_cursor;
        close_struct(data);
    }

    CXCursorKind kind = clang_getCursorKind(cursor);
    if (kind == CXCursor_Namespace) {
        open_namespace(data, cursor);
        data.current_namespaces.push_back(cursor);
        return CXChildVisit_Recurse;
    } else if (struct_kind(kind)) {
        if (clang_Cursor_isNull(data.current_struct)) {
            data.current_struct = cursor;
            open_struct(data, cursor);
            return CXChildVisit_Recurse;
        }
    } else if (kind == CXCursor_CXXMethod) {
        print_member_function(data, cursor);
    }

    return CXChildVisit_Continue;
}

int main (int argc, char* argv[])
{
    CXIndex index = clang_createIndex(0, 1);
    CXTranslationUnit tu = clang_parseTranslationUnit(
        index,
        0,
        argv,
        argc,
        0,
        0,
        CXTranslationUnit_None
    );

    client_data data = {tu, {}, clang_getNullCursor()};

    tu_cursor = clang_getTranslationUnitCursor(tu);
    clang_visitChildren(tu_cursor, visitor, &data);

    if (!clang_Cursor_isNull(data.current_struct))
        close_struct(data);

    while (!data.current_namespaces.empty()) {
        data.current_namespaces.pop_back();
        close_namespace(data);
    }

    clang_disposeTranslationUnit(tu);
    clang_disposeIndex(index);

    return 0;
}
<commit_msg>print() -> print_lines().<commit_after>#include <clang-c/Index.h>
#include <cstdio>

#include <iostream>
#include <vector>

namespace {
    const unsigned int indent_spaces = 4;
}

CXCursor tu_cursor;

struct client_data
{
    CXTranslationUnit tu;
    std::vector<CXCursor> current_namespaces;
    CXCursor current_struct;
};

std::pair<CXToken*, unsigned int>
get_tokens (CXTranslationUnit tu, CXCursor cursor)
{
    CXSourceRange range = clang_getCursorExtent(cursor);
    CXSourceLocation start = clang_getRangeStart(range);
    CXSourceLocation end = clang_getRangeEnd(range);
    unsigned int start_offset, end_offset;

    std::pair<CXToken*, unsigned int> retval(0, 0);
    clang_tokenize(tu, range, &retval.first, &retval.second);

    return retval;
}

void
free_tokens (CXTranslationUnit tu, std::pair<CXToken*, unsigned int> tokens)
{ clang_disposeTokens(tu, tokens.first, tokens.second); }

void print_tokens (CXTranslationUnit tu, CXCursor cursor)
{
    std::pair<CXToken*, unsigned int> tokens = get_tokens(tu, cursor);

    for (unsigned int i = 0; i < tokens.second; ++i) {
        if (i)
            std::cout << " ";
        CXString spelling = clang_getTokenSpelling(tu, tokens.first[i]);
        std::cout << clang_getCString(spelling);
    }
    std::cout << "\n";

    free_tokens(tu, tokens);
}

bool struct_kind (CXCursorKind kind)
{
    switch (kind) {
    case CXCursor_ClassDecl:
    case CXCursor_StructDecl:
    case CXCursor_ClassTemplate:
    case CXCursor_ClassTemplatePartialSpecialization:
        return true;
    }
    return false;
}

std::string indent (const client_data& data)
{
    std::size_t size = data.current_namespaces.size();
    return std::string(size * indent_spaces, ' ');
}

void print_lines (const client_data& data,
                  const char** lines,
                  std::size_t num_lines)
{
    std::string padding(indent_spaces, ' ');
    for (unsigned int i = 0; i < num_lines; ++i) {
        if (lines[i])
            std::cout << indent(data) << padding << lines[i] << "\n";
        else
            std::cout << "\n";
    }
}

void open_struct (const client_data& data, CXCursor struct_cursor)
{
    std::pair<CXToken*, unsigned int> tokens =
        get_tokens(data.tu, struct_cursor);

    std::cout << "\n" << indent(data);

    const std::string open_brace = "{";
    const std::string struct_ = "struct";
    const std::string class_ = "class";

    for (unsigned int i = 0; i < tokens.second; ++i) {
        CXString spelling = clang_getTokenSpelling(data.tu, tokens.first[i]);

        const char* c_str = clang_getCString(spelling);

        if (c_str == open_brace)
            break;

        if (c_str == struct_ || c_str == class_) {
            std::cout << "\n" << indent(data);
        } else if (i) {
            std::cout << " ";
        }

        std::cout << c_str;
    }

    free_tokens(data.tu, tokens);

    std::cout << "\n"
              << indent(data) << "{\n"
              << indent(data) << "public:\n";

    const char* public_interface[] = {
        0,
        "any_printable () = default;",
        0,
        "template <typename T_T__>",
        "any_printable (T_T__ value) :",
        "    handle_ (",
        "        std::make_shared<",
        "            handle<typename std::remove_reference<T_T__>::type>",
        "        >(std::forward<T_T__>(value))",
        "    )",
        "{}",
        0,
        "any_printable (any_printable && rhs) noexcept = default;",
        0,
        "template <typename T_T__>",
        "any_printable & operator= (T_T__ value)",
        "{",
        "    if (handle_.unique())",
        "        *handle_ = std::forward<T_T__>(value);",
        "    else if (!handle_)",
        "        handle_ = std::make_shared<T_T__>(std::forward<T_T__>(value));",
        "    return *this;",
        "}",
        0,
        "any_printable & operator= (any_printable && rhs) noexcept = default;"
    };

    print_lines(data,
                public_interface,
                sizeof(public_interface) / sizeof(const char*));
}

void close_struct (const client_data& data)
{
    std::cout << "\n"
              << indent(data) << "private:\n";

    const char* handle_base_preamble[] = {
        0,
        "struct handle_base",
        "{",
        "    virtual ~handle_base () {}",
        "    virtual std::shared_ptr<handle_base> close () const = 0;",
        0
    };

    print_lines(data,
                handle_base_preamble,
                sizeof(handle_base_preamble) / sizeof(const char*));

    // TODO: pure virtual

    const char* handle_preamble[] = {
        "};",
        0,
        "template <typename T_T__>",
        "struct handle :",
        "    handle_base",
        "{",
        "    template <typename T_T__>",
        "    handle (T_T__ value,",
        "            typename std::enable_if<",
        "                std::is_reference<U_U__>::value",
        "            >::type* = 0) :",
        "        value_ (value)",
        "    {}",
        0,
        "    template <typename U_U__ = T_T__>",
        "    handle (T_T__ value,",
        "            typename std::enable_if<",
        "                !std::is_reference<U_U__>::value,",
        "                int",
        "            >::type* = 0) noexcept :",
        "        value_ (std::move(value))",
        "    {}",
        0,
        "    virtual std::shared_ptr<handle_base> clone () const",
        "    { return std::make_shared<handle>(value_); }"
    };

    print_lines(data,
                handle_preamble,
                sizeof(handle_preamble) / sizeof(const char*));

    // TODO: virtual implementations

    const char* handle_postamble[] = {
        0,
        "    T_T__ value_;",
        "};",
        0,
        "template <typename T_T__>",
        "struct handle<std::reference_wrapper<T_T__>> :",
        "    handle<T_T__ &>",
        "{",
        "    handle (std::reference_wrapper<T_T__> ref) :",
        "        handle<T_T__ &> (ref.get())",
        "    {}",
        "};",
        0,
        "const handle_base & read () const",
        "{ return *handle_; }",
        0,
        "handle_base & write ()",
        "{",
        "    if (!handle_.unique())",
        "        handle_ = handle_->clone();",
        "    return *handle_;",
        "}",
        0,
        "std::shared_ptr<handle_base> handle_;"
    };

    print_lines(data,
                handle_postamble,
                sizeof(handle_postamble) / sizeof(const char*));

    std::cout << "\n"
              << indent(data) << "};\n";
}

void print_member_function(const client_data& data, CXCursor cursor)
{
    std::pair<CXToken*, unsigned int> tokens = get_tokens(data.tu, cursor);

    std::cout << "\n"
              << std::string(indent_spaces, ' ') << indent(data);

    const std::string open_brace = "{";
    const std::string semicolon = ";";

    for (unsigned int i = 0; i < tokens.second; ++i) {
        CXString spelling = clang_getTokenSpelling(data.tu, tokens.first[i]);

        const char* c_str = clang_getCString(spelling);

        if (c_str == open_brace || c_str == semicolon)
            break;

        if (i)
            std::cout << " ";

        std::cout << c_str;
    }

    free_tokens(data.tu, tokens);

    const char* return_str =
        clang_getCursorResultType(cursor).kind == CXType_Void ? "" : "return ";

    std::cout << "\n" << std::string(indent_spaces, ' ') << indent(data)
              << "{ assert(handle_); " << return_str << "handle_->"
              << clang_getCString(clang_getCursorSpelling(cursor))
              << "( ";
    const int args = clang_Cursor_getNumArguments(cursor);
    for (int i = 0; i < args; ++i) {
        if (i)
            std::cout << ", ";
        CXCursor arg_cursor = clang_Cursor_getArgument(cursor, i);
        std::cout << clang_getCString(clang_getCursorSpelling(arg_cursor));
    }
    std::cout << " ); }\n";
}

void open_namespace (const client_data& data, CXCursor namespace_)
{
    std::cout
        << "\n"
        << indent(data)
        << "namespace "
        << clang_getCString(clang_getCursorSpelling(namespace_))
        << " {";
}

void close_namespace (const client_data& data)
{ std::cout << "\n" << indent(data) << "}\n"; }

void dump_cursor (const char* name, CXCursor cursor)
{
    CXCursorKind kind = clang_getCursorKind(cursor);
    CXString kind_spelling = clang_getCursorKindSpelling(kind);
    CXString cursor_spelling = clang_getCursorSpelling(cursor);
    std::cout << name << " "
              << clang_getCString(kind_spelling) << " "
              << clang_getCString(cursor_spelling) << " "
              << "\n";
}

CXChildVisitResult
visitor (CXCursor cursor, CXCursor parent, CXClientData data_)
{
    client_data& data = *static_cast<client_data*>(data_);

#if 0
    std::cout << "\n";
    dump_cursor("cursor", cursor);
    dump_cursor("parent", parent);
#endif

    CXCursor null_cursor = clang_getNullCursor();

    // close open namespaces we have left
    CXCursor enclosing_namespace = parent;
    while (!clang_equalCursors(enclosing_namespace, tu_cursor) &&
           clang_getCursorKind(enclosing_namespace) != CXCursor_Namespace) {
        enclosing_namespace =
            clang_getCursorSemanticParent(enclosing_namespace);
    }
#if 0
    dump_cursor("enclosing_namespace", enclosing_namespace);
#endif
    if (!clang_equalCursors(enclosing_namespace, tu_cursor) &&
        clang_getCursorKind(enclosing_namespace) == CXCursor_Namespace) {
        while (!clang_equalCursors(enclosing_namespace,
                                   data.current_namespaces.back())) {
            data.current_namespaces.pop_back();
            close_namespace(data);
        }
    }

    // close open struct if we have left it
    CXCursor enclosing_struct = parent;
    while (!clang_equalCursors(enclosing_struct, tu_cursor) &&
           !struct_kind(clang_getCursorKind(enclosing_struct))) {
        enclosing_struct = clang_getCursorSemanticParent(enclosing_struct);
    }
#if 0
    dump_cursor("enclosing_struct", enclosing_struct);
#endif
    if (!clang_Cursor_isNull(data.current_struct) &&
        !clang_equalCursors(enclosing_struct, data.current_struct)) {
        data.current_struct = null_cursor;
        close_struct(data);
    }

    CXCursorKind kind = clang_getCursorKind(cursor);
    if (kind == CXCursor_Namespace) {
        open_namespace(data, cursor);
        data.current_namespaces.push_back(cursor);
        return CXChildVisit_Recurse;
    } else if (struct_kind(kind)) {
        if (clang_Cursor_isNull(data.current_struct)) {
            data.current_struct = cursor;
            open_struct(data, cursor);
            return CXChildVisit_Recurse;
        }
    } else if (kind == CXCursor_CXXMethod) {
        print_member_function(data, cursor);
    }

    return CXChildVisit_Continue;
}

int main (int argc, char* argv[])
{
    CXIndex index = clang_createIndex(0, 1);
    CXTranslationUnit tu = clang_parseTranslationUnit(
        index,
        0,
        argv,
        argc,
        0,
        0,
        CXTranslationUnit_None
    );

    client_data data = {tu, {}, clang_getNullCursor()};

    tu_cursor = clang_getTranslationUnitCursor(tu);
    clang_visitChildren(tu_cursor, visitor, &data);

    if (!clang_Cursor_isNull(data.current_struct))
        close_struct(data);

    while (!data.current_namespaces.empty()) {
        data.current_namespaces.pop_back();
        close_namespace(data);
    }

    clang_disposeTranslationUnit(tu);
    clang_disposeIndex(index);

    return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: color.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2008-02-19 13:11:43 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _TOOLS_COLOR_HXX
#define _TOOLS_COLOR_HXX

#ifndef INCLUDED_TOOLSDLLAPI_H
#include "tools/toolsdllapi.h"
#endif

class SvStream;
class ResId;

#ifndef _SOLAR_H
#include <tools/solar.h>
#endif

// --------------------
// - ColorCount-Types -
// --------------------

#define COLCOUNT_MONOCHROM          ((ULONG)2)
#define COLCOUNT_16                 ((ULONG)16)
#define COLCOUNT_256                ((ULONG)256)
#define COLCOUNT_HICOLOR1           (((ULONG)0x00007FFF)+1)
#define COLCOUNT_HICOLOR2           (((ULONG)0x0000FFFF)+1)
#define COLCOUNT_TRUECOLOR          (((ULONG)0x00FFFFFF)+1)

// ---------------
// - Color-Types -
// ---------------

typedef UINT32 ColorData;
#define RGB_COLORDATA( r,g,b )      ((ColorData)(((UINT32)((UINT8)(b))))|(((UINT32)((UINT8)(g)))<<8)|(((UINT32)((UINT8)(r)))<<16))
#define TRGB_COLORDATA( t,r,g,b )   ((ColorData)(((UINT32)((UINT8)(b))))|(((UINT32)((UINT8)(g)))<<8)|(((UINT32)((UINT8)(r)))<<16)|(((UINT32)((UINT8)(t)))<<24))
#define COLORDATA_RED( n )          ((UINT8)((n)>>16))
#define COLORDATA_GREEN( n )        ((UINT8)(((UINT16)(n)) >> 8))
#define COLORDATA_BLUE( n )         ((UINT8)(n))
#define COLORDATA_TRANSPARENCY( n ) ((UINT8)((n)>>24))
#define COLORDATA_RGB( n )          ((ColorData)((n) & 0x00FFFFFF))

#define COL_BLACK                   RGB_COLORDATA( 0x00, 0x00, 0x00 )
#define COL_BLUE                    RGB_COLORDATA( 0x00, 0x00, 0x80 )
#define COL_GREEN                   RGB_COLORDATA( 0x00, 0x80, 0x00 )
#define COL_CYAN                    RGB_COLORDATA( 0x00, 0x80, 0x80 )
#define COL_RED                     RGB_COLORDATA( 0x80, 0x00, 0x00 )
#define COL_MAGENTA                 RGB_COLORDATA( 0x80, 0x00, 0x80 )
#define COL_BROWN                   RGB_COLORDATA( 0x80, 0x80, 0x00 )
#define COL_GRAY                    RGB_COLORDATA( 0x80, 0x80, 0x80 )
#define COL_LIGHTGRAY               RGB_COLORDATA( 0xC0, 0xC0, 0xC0 )
#define COL_LIGHTBLUE               RGB_COLORDATA( 0x00, 0x00, 0xFF )
#define COL_LIGHTGREEN              RGB_COLORDATA( 0x00, 0xFF, 0x00 )
#define COL_LIGHTCYAN               RGB_COLORDATA( 0x00, 0xFF, 0xFF )
#define COL_LIGHTRED                RGB_COLORDATA( 0xFF, 0x00, 0x00 )
#define COL_LIGHTMAGENTA            RGB_COLORDATA( 0xFF, 0x00, 0xFF )
#define COL_YELLOW                  RGB_COLORDATA( 0xFF, 0xFF, 0x00 )
#define COL_WHITE                   RGB_COLORDATA( 0xFF, 0xFF, 0xFF )
#define COL_TRANSPARENT             TRGB_COLORDATA( 0xFF, 0xFF, 0xFF, 0xFF )
#define COL_AUTO                    (UINT32)0xFFFFFFFF
#define COL_AUTHOR1_DARK            RGB_COLORDATA(198, 146, 0)
#define COL_AUTHOR1_NORMAL          RGB_COLORDATA(255, 255, 158)
#define COL_AUTHOR1_LIGHT           RGB_COLORDATA(255, 255, 195)
#define COL_AUTHOR2_DARK            RGB_COLORDATA(6,  70, 162)
#define COL_AUTHOR2_NORMAL          RGB_COLORDATA(216, 232, 255)
#define COL_AUTHOR2_LIGHT           RGB_COLORDATA(233, 242, 255)
#define COL_AUTHOR3_DARK            RGB_COLORDATA(87, 157,  28)
#define COL_AUTHOR3_NORMAL          RGB_COLORDATA(218, 248, 193)
#define COL_AUTHOR3_LIGHT           RGB_COLORDATA(226, 250, 207)
#define COL_AUTHOR4_DARK            RGB_COLORDATA(105,  43, 157)
#define COL_AUTHOR4_NORMAL          RGB_COLORDATA(228, 210, 245)
#define COL_AUTHOR4_LIGHT           RGB_COLORDATA(239, 228, 248)
#define COL_AUTHOR5_DARK            RGB_COLORDATA(197,   0,  11)
#define COL_AUTHOR5_NORMAL          RGB_COLORDATA(254, 205, 208)
#define COL_AUTHOR5_LIGHT           RGB_COLORDATA(255, 227, 229)
#define COL_AUTHOR6_DARK            RGB_COLORDATA(0, 128, 128)
#define COL_AUTHOR6_NORMAL          RGB_COLORDATA(210, 246, 246)
#define COL_AUTHOR6_LIGHT           RGB_COLORDATA(230, 250, 250)
#define COL_AUTHOR7_DARK            RGB_COLORDATA(140, 132,  0)
#define COL_AUTHOR7_NORMAL          RGB_COLORDATA(237, 252, 163)
#define COL_AUTHOR7_LIGHT           RGB_COLORDATA(242, 254, 181)
#define COL_AUTHOR8_DARK            RGB_COLORDATA(53,  85, 107)
#define COL_AUTHOR8_NORMAL          RGB_COLORDATA(211, 222, 232)
#define COL_AUTHOR8_LIGHT           RGB_COLORDATA(226, 234, 241)
#define COL_AUTHOR9_DARK            RGB_COLORDATA(209, 118,   0)
#define COL_AUTHOR9_NORMAL          RGB_COLORDATA(255, 226, 185)
#define COL_AUTHOR9_LIGHT           RGB_COLORDATA(255, 231, 199)

#define COLOR_CHANNEL_MERGE( _def_cDst, _def_cSrc, _def_cSrcTrans ) \
    ((BYTE)((((long)(_def_cDst)-(_def_cSrc))*(_def_cSrcTrans)+(((_def_cSrc)<<8L)|(_def_cDst)))>>8L))

// ---------
// - Color -
// ---------

class TOOLS_DLLPUBLIC Color
{
protected:
    ColorData           mnColor;

public:
                        Color() { mnColor = COL_BLACK; }
                        Color( ColorData nColor ) { mnColor = nColor; }
                        Color( UINT8 nRed, UINT8 nGreen, UINT8 nBlue )
                            { mnColor = RGB_COLORDATA( nRed, nGreen, nBlue ); }
                        Color( UINT8 nTransparency, UINT8 nRed, UINT8 nGreen, UINT8 nBlue )
                            { mnColor = TRGB_COLORDATA( nTransparency, nRed, nGreen, nBlue ); }
                        Color( const ResId& rResId );
                         // This ctor is defined in svtools, not tools!

    void                SetRed( UINT8 nRed );
    UINT8               GetRed() const { return COLORDATA_RED( mnColor ); }
    void                SetGreen( UINT8 nGreen );
    UINT8               GetGreen() const { return COLORDATA_GREEN( mnColor ); }
    void                SetBlue( UINT8 nBlue );
    UINT8               GetBlue() const { return COLORDATA_BLUE( mnColor ); }
    void                SetTransparency( UINT8 nTransparency );
    UINT8               GetTransparency() const { return COLORDATA_TRANSPARENCY( mnColor ); }

    void                SetColor( ColorData nColor ) { mnColor = nColor; }
    ColorData           GetColor() const { return mnColor; }
    ColorData           GetRGBColor() const { return COLORDATA_RGB( mnColor ); }

    UINT8               GetColorError( const Color& rCompareColor ) const;

    UINT8               GetLuminance() const;
    void                IncreaseLuminance( UINT8 cLumInc );
    void                DecreaseLuminance( UINT8 cLumDec );

    void                IncreaseContrast( UINT8 cContInc );
    void                DecreaseContrast( UINT8 cContDec );

    void                Invert();

    void                Merge( const Color& rMergeColor, BYTE cTransparency );

    BOOL                IsRGBEqual( const Color& rColor ) const;

    // comparison with luminance thresholds
    BOOL                IsDark()    const;
    BOOL                IsBright()  const;

    // color space conversion tools
    // the range for h/s/b is:
    // Hue: 0-360 degree
    // Saturation: 0-100 %
    // Brightness: 0-100 %
    static ColorData    HSBtoRGB( USHORT nHue, USHORT nSat, USHORT nBri );
    void                RGBtoHSB( USHORT& nHue, USHORT& nSat, USHORT& nBri ) const;

    BOOL                operator==( const Color& rColor ) const
                            { return (mnColor == rColor.mnColor); }
    BOOL                operator!=( const Color& rColor ) const
                            { return !(Color::operator==( rColor )); }

    SvStream&           Read( SvStream& rIStm, BOOL bNewFormat = TRUE );
    SvStream&           Write( SvStream& rOStm, BOOL bNewFormat = TRUE );

    TOOLS_DLLPUBLIC friend SvStream&    operator>>( SvStream& rIStream, Color& rColor );
    TOOLS_DLLPUBLIC friend SvStream&    operator<<( SvStream& rOStream, const Color& rColor );
};

inline void Color::SetRed( UINT8 nRed )
{
    mnColor &= 0xFF00FFFF;
    mnColor |= ((UINT32)nRed)<<16;
}

inline void Color::SetGreen( UINT8 nGreen )
{
    mnColor &= 0xFFFF00FF;
    mnColor |= ((UINT16)nGreen)<<8;
}

inline void Color::SetBlue( UINT8 nBlue )
{
    mnColor &= 0xFFFFFF00;
    mnColor |= nBlue;
}

inline void Color::SetTransparency( UINT8 nTransparency )
{
    mnColor &= 0x00FFFFFF;
    mnColor |= ((UINT32)nTransparency)<<24;
}

inline BOOL Color::IsRGBEqual( const Color& rColor ) const
{
    return (COLORDATA_RGB( mnColor ) == COLORDATA_RGB( rColor.mnColor ));
}

inline UINT8 Color::GetLuminance() const
{
    return( (UINT8) ( ( COLORDATA_BLUE( mnColor ) * 28UL +
                        COLORDATA_GREEN( mnColor ) * 151UL +
                        COLORDATA_RED( mnColor ) * 77UL ) >> 8UL ) );
}

inline void Color::Merge( const Color& rMergeColor, BYTE cTransparency )
{
    SetRed( COLOR_CHANNEL_MERGE( COLORDATA_RED( mnColor ), COLORDATA_RED( rMergeColor.mnColor ), cTransparency ) );
    SetGreen( COLOR_CHANNEL_MERGE( COLORDATA_GREEN( mnColor ), COLORDATA_GREEN( rMergeColor.mnColor ), cTransparency ) );
    SetBlue( COLOR_CHANNEL_MERGE( COLORDATA_BLUE( mnColor ), COLORDATA_BLUE( rMergeColor.mnColor ), cTransparency ) );
}

#endif // _TOOLS_COLOR_HXX
<commit_msg>INTEGRATION: CWS changefileheader (1.3.22); FILE MERGED 2008/04/01 12:57:19 thb 1.3.22.2: #i85898# Stripping all external header guards 2008/03/28 15:41:07 rt 1.3.22.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: color.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _TOOLS_COLOR_HXX
#define _TOOLS_COLOR_HXX

#include "tools/toolsdllapi.h"

class SvStream;
class ResId;
#include <tools/solar.h>

// --------------------
// - ColorCount-Types -
// --------------------

#define COLCOUNT_MONOCHROM          ((ULONG)2)
#define COLCOUNT_16                 ((ULONG)16)
#define COLCOUNT_256                ((ULONG)256)
#define COLCOUNT_HICOLOR1           (((ULONG)0x00007FFF)+1)
#define COLCOUNT_HICOLOR2           (((ULONG)0x0000FFFF)+1)
#define COLCOUNT_TRUECOLOR          (((ULONG)0x00FFFFFF)+1)

// ---------------
// - Color-Types -
// ---------------

typedef UINT32 ColorData;
#define RGB_COLORDATA( r,g,b )      ((ColorData)(((UINT32)((UINT8)(b))))|(((UINT32)((UINT8)(g)))<<8)|(((UINT32)((UINT8)(r)))<<16))
#define TRGB_COLORDATA( t,r,g,b )   ((ColorData)(((UINT32)((UINT8)(b))))|(((UINT32)((UINT8)(g)))<<8)|(((UINT32)((UINT8)(r)))<<16)|(((UINT32)((UINT8)(t)))<<24))
#define COLORDATA_RED( n )          ((UINT8)((n)>>16))
#define COLORDATA_GREEN( n )        ((UINT8)(((UINT16)(n)) >> 8))
#define COLORDATA_BLUE( n )         ((UINT8)(n))
#define COLORDATA_TRANSPARENCY( n ) ((UINT8)((n)>>24))
#define COLORDATA_RGB( n )          ((ColorData)((n) & 0x00FFFFFF))

#define COL_BLACK                   RGB_COLORDATA( 0x00, 0x00, 0x00 )
#define COL_BLUE                    RGB_COLORDATA( 0x00, 0x00, 0x80 )
#define COL_GREEN                   RGB_COLORDATA( 0x00, 0x80, 0x00 )
#define COL_CYAN                    RGB_COLORDATA( 0x00, 0x80, 0x80 )
#define COL_RED                     RGB_COLORDATA( 0x80, 0x00, 0x00 )
#define COL_MAGENTA                 RGB_COLORDATA( 0x80, 0x00, 0x80 )
#define COL_BROWN                   RGB_COLORDATA( 0x80, 0x80, 0x00 )
#define COL_GRAY                    RGB_COLORDATA( 0x80, 0x80, 0x80 )
#define COL_LIGHTGRAY               RGB_COLORDATA( 0xC0, 0xC0, 0xC0 )
#define COL_LIGHTBLUE               RGB_COLORDATA( 0x00, 0x00, 0xFF )
#define COL_LIGHTGREEN              RGB_COLORDATA( 0x00, 0xFF, 0x00 )
#define COL_LIGHTCYAN               RGB_COLORDATA( 0x00, 0xFF, 0xFF )
#define COL_LIGHTRED                RGB_COLORDATA( 0xFF, 0x00, 0x00 )
#define COL_LIGHTMAGENTA            RGB_COLORDATA( 0xFF, 0x00, 0xFF )
#define COL_YELLOW                  RGB_COLORDATA( 0xFF, 0xFF, 0x00 )
#define COL_WHITE                   RGB_COLORDATA( 0xFF, 0xFF, 0xFF )
#define COL_TRANSPARENT             TRGB_COLORDATA( 0xFF, 0xFF, 0xFF, 0xFF )
#define COL_AUTO                    (UINT32)0xFFFFFFFF
#define COL_AUTHOR1_DARK            RGB_COLORDATA(198, 146, 0)
#define COL_AUTHOR1_NORMAL          RGB_COLORDATA(255, 255, 158)
#define COL_AUTHOR1_LIGHT           RGB_COLORDATA(255, 255, 195)
#define COL_AUTHOR2_DARK            RGB_COLORDATA(6,  70, 162)
#define COL_AUTHOR2_NORMAL          RGB_COLORDATA(216, 232, 255)
#define COL_AUTHOR2_LIGHT           RGB_COLORDATA(233, 242, 255)
#define COL_AUTHOR3_DARK            RGB_COLORDATA(87, 157,  28)
#define COL_AUTHOR3_NORMAL          RGB_COLORDATA(218, 248, 193)
#define COL_AUTHOR3_LIGHT           RGB_COLORDATA(226, 250, 207)
#define COL_AUTHOR4_DARK            RGB_COLORDATA(105,  43, 157)
#define COL_AUTHOR4_NORMAL          RGB_COLORDATA(228, 210, 245)
#define COL_AUTHOR4_LIGHT           RGB_COLORDATA(239, 228, 248)
#define COL_AUTHOR5_DARK            RGB_COLORDATA(197,   0,  11)
#define COL_AUTHOR5_NORMAL          RGB_COLORDATA(254, 205, 208)
#define COL_AUTHOR5_LIGHT           RGB_COLORDATA(255, 227, 229)
#define COL_AUTHOR6_DARK            RGB_COLORDATA(0, 128, 128)
#define COL_AUTHOR6_NORMAL          RGB_COLORDATA(210, 246, 246)
#define COL_AUTHOR6_LIGHT           RGB_COLORDATA(230, 250, 250)
#define COL_AUTHOR7_DARK            RGB_COLORDATA(140, 132,  0)
#define COL_AUTHOR7_NORMAL          RGB_COLORDATA(237, 252, 163)
#define COL_AUTHOR7_LIGHT           RGB_COLORDATA(242, 254, 181)
#define COL_AUTHOR8_DARK            RGB_COLORDATA(53,  85, 107)
#define COL_AUTHOR8_NORMAL          RGB_COLORDATA(211, 222, 232)
#define COL_AUTHOR8_LIGHT           RGB_COLORDATA(226, 234, 241)
#define COL_AUTHOR9_DARK            RGB_COLORDATA(209, 118,   0)
#define COL_AUTHOR9_NORMAL          RGB_COLORDATA(255, 226, 185)
#define COL_AUTHOR9_LIGHT           RGB_COLORDATA(255, 231, 199)

#define COLOR_CHANNEL_MERGE( _def_cDst, _def_cSrc, _def_cSrcTrans ) \
    ((BYTE)((((long)(_def_cDst)-(_def_cSrc))*(_def_cSrcTrans)+(((_def_cSrc)<<8L)|(_def_cDst)))>>8L))

// ---------
// - Color -
// ---------

class TOOLS_DLLPUBLIC Color
{
protected:
    ColorData           mnColor;

public:
                        Color() { mnColor = COL_BLACK; }
                        Color( ColorData nColor ) { mnColor = nColor; }
                        Color( UINT8 nRed, UINT8 nGreen, UINT8 nBlue )
                            { mnColor = RGB_COLORDATA( nRed, nGreen, nBlue ); }
                        Color( UINT8 nTransparency, UINT8 nRed, UINT8 nGreen, UINT8 nBlue )
                            { mnColor = TRGB_COLORDATA( nTransparency, nRed, nGreen, nBlue ); }
                        Color( const ResId& rResId );
                         // This ctor is defined in svtools, not tools!

    void                SetRed( UINT8 nRed );
    UINT8               GetRed() const { return COLORDATA_RED( mnColor ); }
    void                SetGreen( UINT8 nGreen );
    UINT8               GetGreen() const { return COLORDATA_GREEN( mnColor ); }
    void                SetBlue( UINT8 nBlue );
    UINT8               GetBlue() const { return COLORDATA_BLUE( mnColor ); }
    void                SetTransparency( UINT8 nTransparency );
    UINT8               GetTransparency() const { return COLORDATA_TRANSPARENCY( mnColor ); }

    void                SetColor( ColorData nColor ) { mnColor = nColor; }
    ColorData           GetColor() const { return mnColor; }
    ColorData           GetRGBColor() const { return COLORDATA_RGB( mnColor ); }

    UINT8               GetColorError( const Color& rCompareColor ) const;

    UINT8               GetLuminance() const;
    void                IncreaseLuminance( UINT8 cLumInc );
    void                DecreaseLuminance( UINT8 cLumDec );

    void                IncreaseContrast( UINT8 cContInc );
    void                DecreaseContrast( UINT8 cContDec );

    void                Invert();

    void                Merge( const Color& rMergeColor, BYTE cTransparency );

    BOOL                IsRGBEqual( const Color& rColor ) const;

    // comparison with luminance thresholds
    BOOL                IsDark()    const;
    BOOL                IsBright()  const;

    // color space conversion tools
    // the range for h/s/b is:
    // Hue: 0-360 degree
    // Saturation: 0-100 %
    // Brightness: 0-100 %
    static ColorData    HSBtoRGB( USHORT nHue, USHORT nSat, USHORT nBri );
    void                RGBtoHSB( USHORT& nHue, USHORT& nSat, USHORT& nBri ) const;

    BOOL                operator==( const Color& rColor ) const
                            { return (mnColor == rColor.mnColor); }
    BOOL                operator!=( const Color& rColor ) const
                            { return !(Color::operator==( rColor )); }

    SvStream&           Read( SvStream& rIStm, BOOL bNewFormat = TRUE );
    SvStream&           Write( SvStream& rOStm, BOOL bNewFormat = TRUE );

    TOOLS_DLLPUBLIC friend SvStream&    operator>>( SvStream& rIStream, Color& rColor );
    TOOLS_DLLPUBLIC friend SvStream&    operator<<( SvStream& rOStream, const Color& rColor );
};

inline void Color::SetRed( UINT8 nRed )
{
    mnColor &= 0xFF00FFFF;
    mnColor |= ((UINT32)nRed)<<16;
}

inline void Color::SetGreen( UINT8 nGreen )
{
    mnColor &= 0xFFFF00FF;
    mnColor |= ((UINT16)nGreen)<<8;
}

inline void Color::SetBlue( UINT8 nBlue )
{
    mnColor &= 0xFFFFFF00;
    mnColor |= nBlue;
}

inline void Color::SetTransparency( UINT8 nTransparency )
{
    mnColor &= 0x00FFFFFF;
    mnColor |= ((UINT32)nTransparency)<<24;
}

inline BOOL Color::IsRGBEqual( const Color& rColor ) const
{
    return (COLORDATA_RGB( mnColor ) == COLORDATA_RGB( rColor.mnColor ));
}

inline UINT8 Color::GetLuminance() const
{
    return( (UINT8) ( ( COLORDATA_BLUE( mnColor ) * 28UL +
                        COLORDATA_GREEN( mnColor ) * 151UL +
                        COLORDATA_RED( mnColor ) * 77UL ) >> 8UL ) );
}

inline void Color::Merge( const Color& rMergeColor, BYTE cTransparency )
{
    SetRed( COLOR_CHANNEL_MERGE( COLORDATA_RED( mnColor ), COLORDATA_RED( rMergeColor.mnColor ), cTransparency ) );
    SetGreen( COLOR_CHANNEL_MERGE( COLORDATA_GREEN( mnColor ), COLORDATA_GREEN( rMergeColor.mnColor ), cTransparency ) );
    SetBlue( COLOR_CHANNEL_MERGE( COLORDATA_BLUE( mnColor ), COLORDATA_BLUE( rMergeColor.mnColor ), cTransparency ) );
}

#endif // _TOOLS_COLOR_HXX
<|endoftext|>


<commit_before>/**
 *Implement wildcard pattern matching with support for '?' and '*'.
 *'?' Matches any single character. '*' Matches any sequence of
 *characters (including the empty sequence).
 *The matching should cover the entire input string (not partial).
 *The function prototype should be:
 *  bool isMatch(const char *s, const char *p)
 *Some examples:
 *  isMatch("aa","a") → false
 *  isMatch("aa","aa") → true
 *  isMatch("aaa","aa") → false
 *  isMatch("aa", "*") → true
 *  isMatch("aa", "a*") → true
 *  isMatch("ab", "?*") → true
 *  isMatch("aab", "c*a*b") → false
 * */

class Solution {
    public:
        bool isMatch(const char *s, const char *p) {
            if(s == NULL)
                return p == NULL;

            if(*p == '*') {
                while(*p == '*')
                    p++;
                if(*p == '\0')
                    return true;
                while(*s != '\0' && !isMatch(s, p))
                    s++;

                return *s != '\0';
            } else if(*p == '\0' || *s == '\0') {
                return *p == *s;
            } else if(*p == *s || *p == '?') {
                return isMatch(s++, p++);
            } else {
                return false;
            }
        }
};
<commit_msg>wildcard matching iteration<commit_after>/**
 *Implement wildcard pattern matching with support for '?' and '*'.
 *'?' Matches any single character. '*' Matches any sequence of
 *characters (including the empty sequence).
 *The matching should cover the entire input string (not partial).
 *The function prototype should be:
 *  bool isMatch(const char *s, const char *p)
 *Some examples:
 *  isMatch("aa","a") → false
 *  isMatch("aa","aa") → true
 *  isMatch("aaa","aa") → false
 *  isMatch("aa", "*") → true
 *  isMatch("aa", "a*") → true
 *  isMatch("ab", "?*") → true
 *  isMatch("aab", "c*a*b") → false
 * */

class Solution {
    public:
        bool isMatch(const char *s, const char *p) {
            if(s == NULL)
                return p == NULL;

            if(*p == '*') {
                while(*p == '*')
                    p++;
                if(*p == '\0')
                    return true;
                while(*s != '\0' && !isMatch(s, p))
                    s++;

                return *s != '\0';
            } else if(*p == '\0' || *s == '\0') {
                return *p == *s;
            } else if(*p == *s || *p == '?') {
                return isMatch(s++, p++);
            } else {
                return false;
            }
        }

        bool isMatch_iteration(const char *s, const char *p) {
            bool star = false;
            const char *str, *ptr;
            for(str = s, ptr = p; *str; str++, ptr++) {
                switch(*ptr) {
                    case '?':
                        break;
                    case '*':
                        star = true;
                        s = str, p = ptr;
                        while(*p == '*')
                            p++;
                        if(*p == '\0')
                            return true;
                        str = s - 1;
                        ptr = p - 1;
                        break;
                    default:
                        if(*str != *ptr) {
                            if(!star)
                                return false;
                            s++;
                            str = s - 1;
                            ptr = p - 1;
                        }
                }
            }
            while(*ptr == '*')
                ptr++;

            return  *ptr == '\0';
        }
};
<|endoftext|>


<commit_before>#include <bts/blockchain/asset_operations.hpp>
#include <bts/blockchain/chain_interface.hpp>
#include <bts/blockchain/exceptions.hpp>

namespace bts { namespace blockchain {

   bool create_asset_operation::is_power_of_ten( uint64_t n )
   {
      switch( n )
      {
         case 1ll:
         case 10ll:
         case 100ll:
         case 1000ll:
         case 10000ll:
         case 100000ll:
         case 1000000ll:
         case 10000000ll:
         case 100000000ll:
         case 1000000000ll:
         case 10000000000ll:
         case 100000000000ll:
         case 1000000000000ll:
         case 10000000000000ll:
         case 100000000000000ll:
         case 1000000000000000ll:
            return true;
         default:
            return false;
      }
   }

   void create_asset_operation::evaluate( transaction_evaluation_state& eval_state )
   { try {
      if( NOT eval_state._current_state->is_valid_symbol_name( this->symbol ) )
          FC_CAPTURE_AND_THROW( invalid_asset_symbol, (symbol) );

      oasset_record current_asset_record = eval_state._current_state->get_asset_record( this->symbol );
      if( current_asset_record.valid() )
          FC_CAPTURE_AND_THROW( asset_symbol_in_use, (symbol) );

      const asset_id_type asset_id = eval_state._current_state->last_asset_id() + 1;
      current_asset_record = eval_state._current_state->get_asset_record( asset_id );
      if( current_asset_record.valid() )
          FC_CAPTURE_AND_THROW( asset_id_in_use, (asset_id) );

      if( issuer_account_id != asset_record::market_issued_asset )
      {
         const oaccount_record issuer_account_record = eval_state._current_state->get_account_record( this->issuer_account_id );
         if( NOT issuer_account_record.valid() )
             FC_CAPTURE_AND_THROW( unknown_account_id, (issuer_account_id) );
      }

      if( this->maximum_share_supply <= 0 || this->maximum_share_supply > BTS_BLOCKCHAIN_MAX_SHARES )
          FC_CAPTURE_AND_THROW( invalid_asset_amount, (maximum_share_supply) );

      if( NOT is_power_of_ten( this->precision ) )
          FC_CAPTURE_AND_THROW( invalid_precision, (precision) );

      const asset reg_fee( eval_state._current_state->get_asset_registration_fee( this->symbol.size() ), 0 );
      eval_state.required_fees += reg_fee;

      asset_record new_record;
      new_record.id                     = eval_state._current_state->new_asset_id();
      new_record.symbol                 = this->symbol;
      new_record.name                   = this->name;
      new_record.description            = this->description;
      new_record.public_data            = this->public_data;
      new_record.issuer_account_id      = this->issuer_account_id;
      new_record.precision              = this->precision;
      new_record.registration_date      = eval_state._current_state->now();
      new_record.last_update            = new_record.registration_date;
      new_record.current_share_supply   = 0;
      new_record.maximum_share_supply   = this->maximum_share_supply;
      new_record.collected_fees         = 0;

      eval_state._current_state->store_asset_record( new_record );
   } FC_CAPTURE_AND_RETHROW( (*this) ) }

   void update_asset_operation::evaluate( transaction_evaluation_state& eval_state )
   { try {
      FC_ASSERT( !"Not enabled yet!" );

      oasset_record current_asset_record = eval_state._current_state->get_asset_record( this->asset_id );
      if( NOT current_asset_record.valid() )
          FC_CAPTURE_AND_THROW( unknown_asset_id, (asset_id) );

      // Cannot update name, description, max share supply, or precision if any shares have been issued
      if( current_asset_record->current_share_supply > 0 )
      {
          FC_ASSERT( !this->name.valid() );
          FC_ASSERT( !this->description.valid() );
          FC_ASSERT( !this->maximum_share_supply.valid() );
          FC_ASSERT( !this->precision.valid() );
      }

      const account_id_type& current_issuer_account_id = current_asset_record->issuer_account_id;
      const oaccount_record current_issuer_account_record = eval_state._current_state->get_account_record( current_issuer_account_id );
      if( NOT current_issuer_account_record.valid() )
          FC_CAPTURE_AND_THROW( unknown_account_id, (current_issuer_account_id) );

      if( NOT eval_state.account_or_any_parent_has_signed( *current_issuer_account_record ) )
          FC_CAPTURE_AND_THROW( missing_signature, (*current_issuer_account_record) );

      if( this->name.valid() )
          current_asset_record->name = *this->name;

      if( this->description.valid() )
          current_asset_record->description = *this->description;

      if( this->public_data.valid() )
          current_asset_record->public_data = *this->public_data;

      if( this->maximum_share_supply.valid() )
          current_asset_record->maximum_share_supply = *this->maximum_share_supply;

      if( this->precision.valid() )
          current_asset_record->precision = *this->precision;

      current_asset_record->last_update = eval_state._current_state->now();

      eval_state._current_state->store_asset_record( *current_asset_record );
   } FC_CAPTURE_AND_RETHROW( (*this) ) }

   void issue_asset_operation::evaluate( transaction_evaluation_state& eval_state )
   { try {
      oasset_record current_asset_record = eval_state._current_state->get_asset_record( this->amount.asset_id );
      if( NOT current_asset_record.valid() )
          FC_CAPTURE_AND_THROW( unknown_asset_id, (amount.asset_id) );

      if( current_asset_record->is_market_issued() )
          FC_CAPTURE_AND_THROW( not_user_issued, (*current_asset_record) );

      const account_id_type& issuer_account_id = current_asset_record->issuer_account_id;
      const oaccount_record issuer_account_record = eval_state._current_state->get_account_record( issuer_account_id );
      if( NOT issuer_account_record.valid() )
          FC_CAPTURE_AND_THROW( unknown_account_id, (issuer_account_id) );

      if( NOT eval_state.account_or_any_parent_has_signed( *issuer_account_record ) )
          FC_CAPTURE_AND_THROW( missing_signature, (*issuer_account_record) );

      if( this->amount.amount <= 0 )
          FC_CAPTURE_AND_THROW( negative_issue, (amount) );

      if( NOT current_asset_record->can_issue( this->amount ) )
          FC_CAPTURE_AND_THROW( over_issue, (amount)(*current_asset_record) );

      current_asset_record->current_share_supply += this->amount.amount;
      eval_state.add_balance( this->amount );

      current_asset_record->last_update = eval_state._current_state->now();

      eval_state._current_state->store_asset_record( *current_asset_record );
   } FC_CAPTURE_AND_RETHROW( (*this) ) }

} } // bts::blockchain
<commit_msg>Only allow update asset operations that change something; issue #549<commit_after>#include <bts/blockchain/asset_operations.hpp>
#include <bts/blockchain/chain_interface.hpp>
#include <bts/blockchain/exceptions.hpp>

namespace bts { namespace blockchain {

   bool create_asset_operation::is_power_of_ten( uint64_t n )
   {
      switch( n )
      {
         case 1ll:
         case 10ll:
         case 100ll:
         case 1000ll:
         case 10000ll:
         case 100000ll:
         case 1000000ll:
         case 10000000ll:
         case 100000000ll:
         case 1000000000ll:
         case 10000000000ll:
         case 100000000000ll:
         case 1000000000000ll:
         case 10000000000000ll:
         case 100000000000000ll:
         case 1000000000000000ll:
            return true;
         default:
            return false;
      }
   }

   void create_asset_operation::evaluate( transaction_evaluation_state& eval_state )
   { try {
      if( NOT eval_state._current_state->is_valid_symbol_name( this->symbol ) )
          FC_CAPTURE_AND_THROW( invalid_asset_symbol, (symbol) );

      oasset_record current_asset_record = eval_state._current_state->get_asset_record( this->symbol );
      if( current_asset_record.valid() )
          FC_CAPTURE_AND_THROW( asset_symbol_in_use, (symbol) );

      const asset_id_type asset_id = eval_state._current_state->last_asset_id() + 1;
      current_asset_record = eval_state._current_state->get_asset_record( asset_id );
      if( current_asset_record.valid() )
          FC_CAPTURE_AND_THROW( asset_id_in_use, (asset_id) );

      if( issuer_account_id != asset_record::market_issued_asset )
      {
         const oaccount_record issuer_account_record = eval_state._current_state->get_account_record( this->issuer_account_id );
         if( NOT issuer_account_record.valid() )
             FC_CAPTURE_AND_THROW( unknown_account_id, (issuer_account_id) );
      }

      if( this->maximum_share_supply <= 0 || this->maximum_share_supply > BTS_BLOCKCHAIN_MAX_SHARES )
          FC_CAPTURE_AND_THROW( invalid_asset_amount, (maximum_share_supply) );

      if( NOT is_power_of_ten( this->precision ) )
          FC_CAPTURE_AND_THROW( invalid_precision, (precision) );

      const asset reg_fee( eval_state._current_state->get_asset_registration_fee( this->symbol.size() ), 0 );
      eval_state.required_fees += reg_fee;

      asset_record new_record;
      new_record.id                     = eval_state._current_state->new_asset_id();
      new_record.symbol                 = this->symbol;
      new_record.name                   = this->name;
      new_record.description            = this->description;
      new_record.public_data            = this->public_data;
      new_record.issuer_account_id      = this->issuer_account_id;
      new_record.precision              = this->precision;
      new_record.registration_date      = eval_state._current_state->now();
      new_record.last_update            = new_record.registration_date;
      new_record.current_share_supply   = 0;
      new_record.maximum_share_supply   = this->maximum_share_supply;
      new_record.collected_fees         = 0;

      eval_state._current_state->store_asset_record( new_record );
   } FC_CAPTURE_AND_RETHROW( (*this) ) }

#ifndef WIN32
#warning [SOFTFORK] Disable this operation until the next BTS hardfork, then remove
#endif
   void update_asset_operation::evaluate( transaction_evaluation_state& eval_state )
   { try {
      FC_ASSERT( !"Not enabled yet!" );

      oasset_record current_asset_record = eval_state._current_state->get_asset_record( this->asset_id );
      if( NOT current_asset_record.valid() )
          FC_CAPTURE_AND_THROW( unknown_asset_id, (asset_id) );

      // Reject no-ops
      FC_ASSERT( this->name.valid() || this->description.valid() || this->public_data.valid()
                 || this->maximum_share_supply.valid() || this->precision.valid() );

      // Cannot update name, description, max share supply, or precision if any shares have been issued
      if( current_asset_record->current_share_supply > 0 )
      {
          FC_ASSERT( !this->name.valid() );
          FC_ASSERT( !this->description.valid() );
          FC_ASSERT( !this->maximum_share_supply.valid() );
          FC_ASSERT( !this->precision.valid() );
      }

      const account_id_type& current_issuer_account_id = current_asset_record->issuer_account_id;
      const oaccount_record current_issuer_account_record = eval_state._current_state->get_account_record( current_issuer_account_id );
      if( NOT current_issuer_account_record.valid() )
          FC_CAPTURE_AND_THROW( unknown_account_id, (current_issuer_account_id) );

      if( NOT eval_state.account_or_any_parent_has_signed( *current_issuer_account_record ) )
          FC_CAPTURE_AND_THROW( missing_signature, (*current_issuer_account_record) );

      if( this->name.valid() )
          current_asset_record->name = *this->name;

      if( this->description.valid() )
          current_asset_record->description = *this->description;

      if( this->public_data.valid() )
          current_asset_record->public_data = *this->public_data;

      if( this->maximum_share_supply.valid() )
          current_asset_record->maximum_share_supply = *this->maximum_share_supply;

      if( this->precision.valid() )
          current_asset_record->precision = *this->precision;

      current_asset_record->last_update = eval_state._current_state->now();

      eval_state._current_state->store_asset_record( *current_asset_record );
   } FC_CAPTURE_AND_RETHROW( (*this) ) }

   void issue_asset_operation::evaluate( transaction_evaluation_state& eval_state )
   { try {
      oasset_record current_asset_record = eval_state._current_state->get_asset_record( this->amount.asset_id );
      if( NOT current_asset_record.valid() )
          FC_CAPTURE_AND_THROW( unknown_asset_id, (amount.asset_id) );

      if( current_asset_record->is_market_issued() )
          FC_CAPTURE_AND_THROW( not_user_issued, (*current_asset_record) );

      const account_id_type& issuer_account_id = current_asset_record->issuer_account_id;
      const oaccount_record issuer_account_record = eval_state._current_state->get_account_record( issuer_account_id );
      if( NOT issuer_account_record.valid() )
          FC_CAPTURE_AND_THROW( unknown_account_id, (issuer_account_id) );

      if( NOT eval_state.account_or_any_parent_has_signed( *issuer_account_record ) )
          FC_CAPTURE_AND_THROW( missing_signature, (*issuer_account_record) );

      if( this->amount.amount <= 0 )
          FC_CAPTURE_AND_THROW( negative_issue, (amount) );

      if( NOT current_asset_record->can_issue( this->amount ) )
          FC_CAPTURE_AND_THROW( over_issue, (amount)(*current_asset_record) );

      current_asset_record->current_share_supply += this->amount.amount;
      eval_state.add_balance( this->amount );

      current_asset_record->last_update = eval_state._current_state->now();

      eval_state._current_state->store_asset_record( *current_asset_record );
   } FC_CAPTURE_AND_RETHROW( (*this) ) }

} } // bts::blockchain
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
 */

#ifndef UAVCAN_BUILD_CONFIG_HPP_INCLUDED
#define UAVCAN_BUILD_CONFIG_HPP_INCLUDED

/**
 * UAVCAN version definition
 */
#define UAVCAN_VERSION_MAJOR    0
#define UAVCAN_VERSION_MINOR    1

/**
 * UAVCAN_CPP_VERSION - version of the C++ standard used during compilation.
 * This definition contains the integer year number after which the standard was named:
 *  - 2003 for C++03
 *  - 2011 for C++11
 *
 * This config automatically sets according to the actual C++ standard used by the compiler.
 *
 * In C++03 mode the library has almost zero dependency on the C++ standard library, which allows
 * to use it on platforms with a very limited C++ support. On the other hand, C++11 mode requires
 * many parts of the standard library (e.g. <functional>), thus the user might want to force older
 * standard than used by the compiler, in which case this symbol can be overridden manually via
 * compiler flags.
 */
#define UAVCAN_CPP11    2011
#define UAVCAN_CPP03    2003

#ifndef UAVCAN_CPP_VERSION
# if __cplusplus > 201200
#  error Unsupported C++ standard
# elif (__cplusplus > 201100) || defined(__GXX_EXPERIMENTAL_CXX0X__)
#  define UAVCAN_CPP_VERSION    UAVCAN_CPP11
# else
#  define UAVCAN_CPP_VERSION    UAVCAN_CPP03
# endif
#endif

/**
 * This macro enables built-in runtime checks and debug output via printf().
 * Should be used only for library development.
 */
#ifndef UAVCAN_DEBUG
# define UAVCAN_DEBUG 0
#endif

/**
 * UAVCAN can be explicitly told to ignore exceptions, or it can be detected automatically.
 * Autodetection is not expected to work with all compilers, so it's safer to define it explicitly.
 * If the autodetection fails, exceptions will be disabled by default.
 */
#ifndef UAVCAN_EXCEPTIONS
# if defined(__EXCEPTIONS) || defined(_HAS_EXCEPTIONS)
#  define UAVCAN_EXCEPTIONS  1
# else
#  define UAVCAN_EXCEPTIONS  0
# endif
#endif

/**
 * This specification is used by some error reporting functions like in the Logger class.
 * The default can be overriden by defining the macro UAVCAN_NOEXCEPT explicitly, e.g. via compiler options.
 */
#ifndef UAVCAN_NOEXCEPT
# if UAVCAN_EXCEPTIONS
#  if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
#   define UAVCAN_NOEXCEPT noexcept
#  else
#   define UAVCAN_NOEXCEPT throw()
#  endif
# else
#  define UAVCAN_NOEXCEPT
# endif
#endif

/**
 * Struct layout control.
 * Set UAVCAN_PACK_STRUCTS=1 and define UAVCAN_PACKED_BEGIN and UAVCAN_PACKED_END to reduce memory usage.
 * THIS MAY BREAK THE CODE.
 */
#ifndef UAVCAN_PACK_STRUCTS
# define UAVCAN_PACK_STRUCTS    0
#endif
#ifndef UAVCAN_PACKED_BEGIN
# define UAVCAN_PACKED_BEGIN
#endif
#ifndef UAVCAN_PACKED_END
# define UAVCAN_PACKED_END
#endif

/**
 * Declaration visibility
 * http://gcc.gnu.org/wiki/Visibility
 */
#ifndef UAVCAN_EXPORT
# define UAVCAN_EXPORT
#endif

/**
 * Trade-off between ROM/RAM usage and functionality/determinism.
 * Note that this feature is not well tested and should be avoided.
 * Use code search for UAVCAN_TINY to find what functionality will be disabled.
 * This is particularly useful for embedded systems with less than 40kB of ROM.
 */
#ifndef UAVCAN_TINY
# define UAVCAN_TINY 0
#endif

/**
 * It might make sense to remove toString() methods for an embedded system.
 * If the autodetect fails, toString() will be disabled, so it's pretty safe by default.
 */
#ifndef UAVCAN_TOSTRING
// Objective is to make sure that we're NOT on a resource constrained platform
# if defined(__linux__) || defined(__linux) || defined(__APPLE__) || defined(_WIN64) || defined(_WIN32)
#  define UAVCAN_TOSTRING 1
# else
#  define UAVCAN_TOSTRING 0
# endif
#endif

#if UAVCAN_TOSTRING
# include <string>
# include <cstdio>
#endif

/**
 * Some C++ implementations are half-broken because they don't implement the placement new operator.
 * If UAVCAN_IMPLEMENT_PLACEMENT_NEW is defined, libuavcan will implement its own operator new (std::size_t, void*)
 * and its delete() counterpart, instead of relying on the standard header <new>.
 */
#ifndef UAVCAN_IMPLEMENT_PLACEMENT_NEW
# define UAVCAN_IMPLEMENT_PLACEMENT_NEW 0
#endif

/**
 * Run time checks.
 * Resolves to the standard assert() by default.
 * Disabled completely if UAVCAN_NO_ASSERTIONS is defined.
 */
#ifndef UAVCAN_ASSERT
# ifndef UAVCAN_NO_ASSERTIONS
#  define UAVCAN_NO_ASSERTIONS 0
# endif
# if UAVCAN_NO_ASSERTIONS
#  define UAVCAN_ASSERT(x)
# else
#  define UAVCAN_ASSERT(x) assert(x)
# endif
#endif

namespace uavcan
{
/**
 * Memory pool block size.
 *
 * The default of 64 bytes should be OK for any target arch up to AMD64 and any compiler.
 *
 * The library leverages compile-time checks to ensure that all types that are subject to dynamic allocation
 * fit this size, otherwise compilation fails.
 *
 * For platforms featuring small pointer width (16..32 bits), UAVCAN_MEM_POOL_BLOCK_SIZE can often be safely
 * reduced to 56 or even 48 bytes, which leads to lower memory footprint.
 *
 * Note that the pool block size shall be aligned at biggest alignment of the target platform (detected and
 * checked automatically at compile time).
 */
#ifdef UAVCAN_MEM_POOL_BLOCK_SIZE
/// Explicitly specified by the user.
static const unsigned MemPoolBlockSize = UAVCAN_MEM_POOL_BLOCK_SIZE;
#elif defined(__BIGGEST_ALIGNMENT__) && (__BIGGEST_ALIGNMENT__ <= 8)
/// Convenient default for GCC-like compilers - if alignment allows, pool block size can be safely reduced.
static const unsigned MemPoolBlockSize = 56;
#else
/// Safe default that should be OK for any platform.
static const unsigned MemPoolBlockSize = 64;
#endif

#ifdef __BIGGEST_ALIGNMENT__
static const unsigned MemPoolAlignment = __BIGGEST_ALIGNMENT__;
#else
static const unsigned MemPoolAlignment = 16;
#endif

typedef char _alignment_check_for_MEM_POOL_BLOCK_SIZE[((MemPoolBlockSize & (MemPoolAlignment - 1)) == 0) ? 1 : -1];

/**
 * This class that allows to check at compile time whether type T can be allocated using the memory pool.
 * If the check fails, compilation fails.
 */
template <typename T>
struct UAVCAN_EXPORT IsDynamicallyAllocatable
{
    static void check()
    {
        char dummy[(sizeof(T) <= MemPoolBlockSize) ? 1 : -1] = { '0' };
        (void)dummy;
    }
};

/**
 * Float comparison precision.
 * For details refer to:
 *  http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
 *  https://code.google.com/p/googletest/source/browse/trunk/include/gtest/internal/gtest-internal.h
 */
#ifdef UAVCAN_FLOAT_COMPARISON_EPSILON_MULT
static const unsigned FloatComparisonEpsilonMult = UAVCAN_FLOAT_COMPARISON_EPSILON_MULT;
#else
static const unsigned FloatComparisonEpsilonMult = 10;
#endif

}

#endif // UAVCAN_BUILD_CONFIG_HPP_INCLUDED
<commit_msg>UAVCAN_VERSION_NUMBER set to 1.0. Although it is not a release yet, no major changes are anticipated<commit_after>/*
 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
 */

#ifndef UAVCAN_BUILD_CONFIG_HPP_INCLUDED
#define UAVCAN_BUILD_CONFIG_HPP_INCLUDED

/**
 * UAVCAN version definition
 */
#define UAVCAN_VERSION_MAJOR    1
#define UAVCAN_VERSION_MINOR    0

/**
 * UAVCAN_CPP_VERSION - version of the C++ standard used during compilation.
 * This definition contains the integer year number after which the standard was named:
 *  - 2003 for C++03
 *  - 2011 for C++11
 *
 * This config automatically sets according to the actual C++ standard used by the compiler.
 *
 * In C++03 mode the library has almost zero dependency on the C++ standard library, which allows
 * to use it on platforms with a very limited C++ support. On the other hand, C++11 mode requires
 * many parts of the standard library (e.g. <functional>), thus the user might want to force older
 * standard than used by the compiler, in which case this symbol can be overridden manually via
 * compiler flags.
 */
#define UAVCAN_CPP11    2011
#define UAVCAN_CPP03    2003

#ifndef UAVCAN_CPP_VERSION
# if __cplusplus > 201200
#  error Unsupported C++ standard
# elif (__cplusplus > 201100) || defined(__GXX_EXPERIMENTAL_CXX0X__)
#  define UAVCAN_CPP_VERSION    UAVCAN_CPP11
# else
#  define UAVCAN_CPP_VERSION    UAVCAN_CPP03
# endif
#endif

/**
 * This macro enables built-in runtime checks and debug output via printf().
 * Should be used only for library development.
 */
#ifndef UAVCAN_DEBUG
# define UAVCAN_DEBUG 0
#endif

/**
 * UAVCAN can be explicitly told to ignore exceptions, or it can be detected automatically.
 * Autodetection is not expected to work with all compilers, so it's safer to define it explicitly.
 * If the autodetection fails, exceptions will be disabled by default.
 */
#ifndef UAVCAN_EXCEPTIONS
# if defined(__EXCEPTIONS) || defined(_HAS_EXCEPTIONS)
#  define UAVCAN_EXCEPTIONS  1
# else
#  define UAVCAN_EXCEPTIONS  0
# endif
#endif

/**
 * This specification is used by some error reporting functions like in the Logger class.
 * The default can be overriden by defining the macro UAVCAN_NOEXCEPT explicitly, e.g. via compiler options.
 */
#ifndef UAVCAN_NOEXCEPT
# if UAVCAN_EXCEPTIONS
#  if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
#   define UAVCAN_NOEXCEPT noexcept
#  else
#   define UAVCAN_NOEXCEPT throw()
#  endif
# else
#  define UAVCAN_NOEXCEPT
# endif
#endif

/**
 * Struct layout control.
 * Set UAVCAN_PACK_STRUCTS=1 and define UAVCAN_PACKED_BEGIN and UAVCAN_PACKED_END to reduce memory usage.
 * THIS MAY BREAK THE CODE.
 */
#ifndef UAVCAN_PACK_STRUCTS
# define UAVCAN_PACK_STRUCTS    0
#endif
#ifndef UAVCAN_PACKED_BEGIN
# define UAVCAN_PACKED_BEGIN
#endif
#ifndef UAVCAN_PACKED_END
# define UAVCAN_PACKED_END
#endif

/**
 * Declaration visibility
 * http://gcc.gnu.org/wiki/Visibility
 */
#ifndef UAVCAN_EXPORT
# define UAVCAN_EXPORT
#endif

/**
 * Trade-off between ROM/RAM usage and functionality/determinism.
 * Note that this feature is not well tested and should be avoided.
 * Use code search for UAVCAN_TINY to find what functionality will be disabled.
 * This is particularly useful for embedded systems with less than 40kB of ROM.
 */
#ifndef UAVCAN_TINY
# define UAVCAN_TINY 0
#endif

/**
 * It might make sense to remove toString() methods for an embedded system.
 * If the autodetect fails, toString() will be disabled, so it's pretty safe by default.
 */
#ifndef UAVCAN_TOSTRING
// Objective is to make sure that we're NOT on a resource constrained platform
# if defined(__linux__) || defined(__linux) || defined(__APPLE__) || defined(_WIN64) || defined(_WIN32)
#  define UAVCAN_TOSTRING 1
# else
#  define UAVCAN_TOSTRING 0
# endif
#endif

#if UAVCAN_TOSTRING
# include <string>
# include <cstdio>
#endif

/**
 * Some C++ implementations are half-broken because they don't implement the placement new operator.
 * If UAVCAN_IMPLEMENT_PLACEMENT_NEW is defined, libuavcan will implement its own operator new (std::size_t, void*)
 * and its delete() counterpart, instead of relying on the standard header <new>.
 */
#ifndef UAVCAN_IMPLEMENT_PLACEMENT_NEW
# define UAVCAN_IMPLEMENT_PLACEMENT_NEW 0
#endif

/**
 * Run time checks.
 * Resolves to the standard assert() by default.
 * Disabled completely if UAVCAN_NO_ASSERTIONS is defined.
 */
#ifndef UAVCAN_ASSERT
# ifndef UAVCAN_NO_ASSERTIONS
#  define UAVCAN_NO_ASSERTIONS 0
# endif
# if UAVCAN_NO_ASSERTIONS
#  define UAVCAN_ASSERT(x)
# else
#  define UAVCAN_ASSERT(x) assert(x)
# endif
#endif

namespace uavcan
{
/**
 * Memory pool block size.
 *
 * The default of 64 bytes should be OK for any target arch up to AMD64 and any compiler.
 *
 * The library leverages compile-time checks to ensure that all types that are subject to dynamic allocation
 * fit this size, otherwise compilation fails.
 *
 * For platforms featuring small pointer width (16..32 bits), UAVCAN_MEM_POOL_BLOCK_SIZE can often be safely
 * reduced to 56 or even 48 bytes, which leads to lower memory footprint.
 *
 * Note that the pool block size shall be aligned at biggest alignment of the target platform (detected and
 * checked automatically at compile time).
 */
#ifdef UAVCAN_MEM_POOL_BLOCK_SIZE
/// Explicitly specified by the user.
static const unsigned MemPoolBlockSize = UAVCAN_MEM_POOL_BLOCK_SIZE;
#elif defined(__BIGGEST_ALIGNMENT__) && (__BIGGEST_ALIGNMENT__ <= 8)
/// Convenient default for GCC-like compilers - if alignment allows, pool block size can be safely reduced.
static const unsigned MemPoolBlockSize = 56;
#else
/// Safe default that should be OK for any platform.
static const unsigned MemPoolBlockSize = 64;
#endif

#ifdef __BIGGEST_ALIGNMENT__
static const unsigned MemPoolAlignment = __BIGGEST_ALIGNMENT__;
#else
static const unsigned MemPoolAlignment = 16;
#endif

typedef char _alignment_check_for_MEM_POOL_BLOCK_SIZE[((MemPoolBlockSize & (MemPoolAlignment - 1)) == 0) ? 1 : -1];

/**
 * This class that allows to check at compile time whether type T can be allocated using the memory pool.
 * If the check fails, compilation fails.
 */
template <typename T>
struct UAVCAN_EXPORT IsDynamicallyAllocatable
{
    static void check()
    {
        char dummy[(sizeof(T) <= MemPoolBlockSize) ? 1 : -1] = { '0' };
        (void)dummy;
    }
};

/**
 * Float comparison precision.
 * For details refer to:
 *  http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
 *  https://code.google.com/p/googletest/source/browse/trunk/include/gtest/internal/gtest-internal.h
 */
#ifdef UAVCAN_FLOAT_COMPARISON_EPSILON_MULT
static const unsigned FloatComparisonEpsilonMult = UAVCAN_FLOAT_COMPARISON_EPSILON_MULT;
#else
static const unsigned FloatComparisonEpsilonMult = 10;
#endif

}

#endif // UAVCAN_BUILD_CONFIG_HPP_INCLUDED
<|endoftext|>


<commit_before>/************************************************
 *  map_iterator.hpp
 *  ESA++
 *
 *  Copyright (c) 2014, Chi-En Wu
 *  Distributed under The BSD 3-Clause License
 ************************************************/

#ifndef ESAPP_MAP_ITERATOR_HPP_
#define ESAPP_MAP_ITERATOR_HPP_

#include <type_traits>

#include "generator.hpp"

namespace esapp
{

template <typename T, typename I> class map_iterator;

/************************************************
 * Inline Helper Function(s)
 ************************************************/

template <typename Transform, typename Iterable>
inline auto make_map_iterator(Transform const &transform,
                              Iterable const &iterable)
    -> map_iterator<Transform, decltype(iterable.begin())>
{
    typedef decltype(make_map_iterator(transform, iterable)) it_t;
    return it_t(transform, iterable.begin(), iterable.end());
}

/************************************************
 * Declaration: class map_iterator
 ************************************************/

template <typename Transform, typename Iterator>
class map_iterator
    : public generator<
        map_iterator<Transform, Iterator>,
        Iterator,
        typename std::result_of<
            Transform(decltype(*std::declval<Iterator>()))
        >::type
    >
{
private: // Private Type(s)
    typedef generator<
        map_iterator,
        Iterator,
        typename std::result_of<
            Transform(decltype(*std::declval<Iterator>()))
        >::type
    > supercls_t;

public: // Public Type(s)
    typedef typename supercls_t::iterator_category iterator_category;
    typedef typename supercls_t::value_type value_type;
    typedef typename supercls_t::reference reference;
    typedef typename supercls_t::pointer pointer;
    typedef typename supercls_t::difference_type difference_type;
    typedef typename supercls_t::input_iterator input_iterator;

    typedef Transform transform;

public: // Public Method(s)
    map_iterator(void) = default;
    map_iterator(transform const &trans,
                 input_iterator const &begin,
                 input_iterator const &end = input_iterator());
    map_iterator(map_iterator const &it) = default;

    map_iterator end(void) const;
    void next(void);
    reference dereference(void) const;

private: // Private Property(ies)
    transform trans_;
    value_type val_;
}; // class map_iterator

/************************************************
 * Implementation: class map_iterator
 ************************************************/

template <typename T, typename I>
inline map_iterator<T, I>::map_iterator(transform const &trans,
                                        input_iterator const &begin,
                                        input_iterator const &end)
    : supercls_t(begin, end), trans_(trans)
{
    if (this->it_ != this->end_)
    {
        val_ = trans_(*(this->it_));
    }
}

template <typename T, typename I>
inline map_iterator<T, I> map_iterator<T, I>::end(void) const
{
    return map_iterator(trans_, this->end_, this->end_);
}

template <typename T, typename I>
inline void map_iterator<T, I>::next(void)
{
    val_ = trans_(*(++(this->it_)));
}

template <typename T, typename I>
inline typename map_iterator<T, I>::reference
map_iterator<T, I>::dereference(void) const
{
    return val_;
}

} // namespace esapp

#endif // ESAPP_MAP_ITERATOR_HPP_
<commit_msg>Fix map_iterator<commit_after>/************************************************
 *  map_iterator.hpp
 *  ESA++
 *
 *  Copyright (c) 2014, Chi-En Wu
 *  Distributed under The BSD 3-Clause License
 ************************************************/

#ifndef ESAPP_MAP_ITERATOR_HPP_
#define ESAPP_MAP_ITERATOR_HPP_

#include <type_traits>

#include "generator.hpp"

namespace esapp
{

template <typename T, typename I> class map_iterator;

/************************************************
 * Inline Helper Function(s)
 ************************************************/

template <typename Transform, typename Iterable>
inline auto make_map_iterator(Transform const &transform,
                              Iterable const &iterable)
    -> map_iterator<Transform, decltype(iterable.begin())>
{
    typedef decltype(make_map_iterator(transform, iterable)) it_t;
    return it_t(transform, iterable.begin(), iterable.end());
}

/************************************************
 * Declaration: class map_iterator
 ************************************************/

template <typename Transform, typename Iterator>
class map_iterator
    : public generator<
        map_iterator<Transform, Iterator>,
        Iterator,
        typename std::result_of<
            Transform(decltype(*std::declval<Iterator>()))
        >::type
    >
{
private: // Private Type(s)
    typedef generator<
        map_iterator,
        Iterator,
        typename std::result_of<
            Transform(decltype(*std::declval<Iterator>()))
        >::type
    > supercls_t;

public: // Public Type(s)
    typedef typename supercls_t::iterator_category iterator_category;
    typedef typename supercls_t::value_type value_type;
    typedef typename supercls_t::reference reference;
    typedef typename supercls_t::pointer pointer;
    typedef typename supercls_t::difference_type difference_type;
    typedef typename supercls_t::input_iterator input_iterator;

    typedef Transform transform;

public: // Public Method(s)
    map_iterator(void) = default;
    map_iterator(transform const &trans,
                 input_iterator const &begin,
                 input_iterator const &end = input_iterator());
    map_iterator(map_iterator const &it) = default;

    map_iterator end(void) const;
    void next(void);
    reference dereference(void) const;
    bool equal(map_iterator const &it) const;

private: // Private Property(ies)
    transform trans_;
    value_type val_;
    bool has_next_;
}; // class map_iterator

/************************************************
 * Implementation: class map_iterator
 ************************************************/

template <typename T, typename I>
inline map_iterator<T, I>::map_iterator(transform const &trans,
                                        input_iterator const &begin,
                                        input_iterator const &end)
    : supercls_t(begin, end), trans_(trans)
{
    next();
}

template <typename T, typename I>
inline map_iterator<T, I> map_iterator<T, I>::end(void) const
{
    return map_iterator(trans_, this->end_, this->end_);
}

template <typename T, typename I>
inline void map_iterator<T, I>::next(void)
{
    has_next_ = this->it_ != this->end_;
    if (!has_next_) { return; }

    val_ = trans_(*(this->it_));
    this->it_++;
}

template <typename T, typename I>
inline typename map_iterator<T, I>::reference
map_iterator<T, I>::dereference(void) const
{
    return val_;
}

template <typename T, typename I>
inline bool map_iterator<T, I>::equal(map_iterator const &it) const
{
    return this->it_ == it.it_ && has_next_ == it.has_next_;
}

} // namespace esapp

#endif // ESAPP_MAP_ITERATOR_HPP_
<|endoftext|>