<commit_before>#include "intersect.h"

using namespace Trinity;

void Trinity::intersect_impl(const uint64_t stopwordsMask,
                             const std::vector<std::set<str8_t>> &tokens,
                             IndexSource *__restrict__ const src, masked_documents_registry *const __restrict__ maskedDocumentsRegistry, std::vector<std::pair<uint64_t, uint32_t>> *const out)
{

        static constexpr bool trace{false};
        struct tracked
        {
                Codecs::Decoder *dec;
                uint8_t tokenIdx;
        } remaining[512];

        Dexpect(tokens.size() <= sizeof(uint64_t) << 3);
        Dexpect(out);

        uint64_t origMask{0}; // we don't want to match the original query
        uint16_t rem{0};

        for (uint8_t i{0}; i != tokens.size(); ++i)
        {
                for (const auto &token : tokens[i])
                {
                        if (const auto tctx = src->term_ctx(token); tctx.documents)
                        {
                                auto dec = src->new_postings_decoder(token, tctx);

                                dec->begin();
                                remaining[rem++] = {dec, i};
                                origMask |= uint64_t(1u) << i;

                                if (trace)
                                        SLog("For [", token, "] ", tctx.documents, "\n");
                        }
                        else if (trace)
                                SLog("Unknown for [", token, "]\n");
                }
        }

        if (!rem)
                return;

        struct ctx
        {
                uint64_t mapPrev{0};
                uint8_t indexPrev{0};

                struct match
                {
                        uint64_t v;
                        uint32_t cnt;
                };

                std::vector<match> matches;

                void consider(const uint64_t map)
                {
                        if (map == mapPrev)
                                ++matches[indexPrev].cnt;
                        else
                        {
                                auto matchesCnt = matches.size();
                                auto all = matches.data();

                                mapPrev = map;
                                for (uint8_t i{0}; i < matchesCnt;)
                                {
#if 1
                                        if (const auto v = all[i].v; (v & map) == map)
                                        {
                                                // [wars jedi] [star wars jedi]
                                                if (map == v)
                                                        ++all[i].cnt;
                                                indexPrev = i;
                                                return;
                                        }
                                        else if ((map & v) == v)
                                        {
                                                // [star wars return jedi] [wars jedi]
                                                matches[i] = matches.back();
                                                matches.pop_back();
                                                --matchesCnt;
                                        }
#else
                                        if (all[i].v == map)
                                        {
                                                ++all[i].cnt;
                                                indexPrev = i;
                                                return;
                                        }
#endif
                                        else
                                                ++i;
                                }

                                indexPrev = matchesCnt;
                                matches.push_back({map, 1});
                        }
                }

                void finalize()
                {
                        std::sort(matches.begin(), matches.end(), [](const auto &a, const auto &b) noexcept {
                                const auto r = int8_t(SwitchBitOps::PopCnt(b.v)) - int8_t(SwitchBitOps::PopCnt(a.v));

                                return r < 0 || (!r && b.cnt < a.cnt);
                        });
                }
        };

        uint16_t selected[sizeof_array(remaining)];
        ctx c;
        const auto before = Timings::Microseconds::Tick();

        for (;;)
        {
                uint16_t cnt{1};
                docid_t lowest;
                const auto &it = remaining[0];
                uint64_t mask = uint64_t(1u) << it.tokenIdx;
                uint8_t first{0}, last{0};

                selected[0] = 0;
                lowest = it.dec->curDocument.id;
                for (uint32_t i{1}; i != rem; ++i)
                {
                        const auto &it = remaining[i];

                        // SLog("For [", tokens[it.tokenIdx], "] ", it.dec->curDocument.id, "\n");

                        if (const auto docID = it.dec->curDocument.id; docID == lowest)
                        {
                                const auto m = uint64_t(1u) << it.tokenIdx;

                                mask |= m;
                                selected[cnt++] = i;
                                last = i;
                        }
                        else if (docID < lowest)
                        {
                                mask = uint64_t(1u) << it.tokenIdx;
                                selected[0] = i;
                                cnt = 1;
                                lowest = docID;
                                first = last = i;
                        }

                l100:;
                }

                if (mask != origMask)
                {
                        if (0 == (stopwordsMask & ((uint64_t(1) << first) | (uint64_t(1) << last))))
                        {
                                if (!maskedDocumentsRegistry->test(lowest))
                                        c.consider(mask);
                        }
                }

                while (cnt)
                {
                        const auto idx = selected[--cnt];

                        if (!remaining[idx].dec->next())
                        {
                                delete remaining[idx].dec;
                                if (--rem == 0)
                                        goto l10;
                                else
                                        remaining[idx] = remaining[rem];
                        }
                }
        }

l10:
        c.finalize();
        SLog(duration_repr(Timings::Microseconds::Since(before)), " to intersect, c.matches.size = ", c.matches.size(), "\n");

        for (const auto &it : c.matches)
        {
                if (trace)
                        SLog("output:", it.v, ", cnt = ", it.cnt, ", popcnt = ", SwitchBitOps::PopCnt(it.v), "\n");
                out->push_back({it.v, it.cnt});
        }
}

std::vector<std::pair<uint64_t, uint32_t>> Trinity::intersect(const uint64_t stopwordsMask, const std::vector<std::set<str8_t>> &tokens, IndexSourcesCollection *collection)
{
        std::vector<std::pair<uint64_t, uint32_t>> out;
        const auto n = collection->sources.size();

        // TODO: use std::async()?
        for (uint32_t i{0}; i != n; ++i)
        {
                auto source = collection->sources[i];
                auto scanner = collection->scanner_registry_for(i);

                intersect_impl(stopwordsMask, tokens, source, scanner.get(), &out);
        }

        std::sort(out.begin(), out.end(), [](const auto &a, const auto &b) { return a.first < b.first; });

        auto o = out.data();
        for (const auto *p = out.data(), *const e = p + out.size(); p != e;)
        {
                const auto mask = p->first;
                auto cnt = p->second;

                for (++p; p != e && p->first == mask; ++p)
                        continue;

                *o++ = {mask, cnt};
        }

        out.resize(o - out.data());
        return out;
}

uint8_t Trinity::intersection_indices(uint64_t mask, uint8_t *const out)
{
        uint8_t shift{0}, collected{0};

        do
        {
                auto idx = SwitchBitOps::LeastSignificantBitSet(mask);
                const auto translated = idx + shift - 1;

                out[collected++] = translated;

                mask >>= idx;
                shift += idx;
        } while (mask);

        return collected;
}

std::vector<std::pair<range_base<str8_t *, uint8_t>, std::size_t>> Trinity::intersection_alternatives(const query &originalQuery, query &rewrittenQuery, IndexSourcesCollection &collection, simple_allocator *const a)
{
        static constexpr bool trace{false};
        std::vector<std::pair<range_base<str8_t *, uint8_t>, std::size_t>> resp;

        if (!originalQuery.can_intersect())
                return resp;

        auto &q{rewrittenQuery};

        // This works because Trinity::rewrite_query() sets rewrite_ctx for each token/phrase
        std::vector<Trinity::phrase *> v;
        std::set<str8_t> seen;

        for (const auto n : q.nodes())
        {
                if (n->type == Trinity::ast_node::Type::Token)
                        v.push_back(n->p);
        }

        std::sort(v.begin(), v.end(), [](const auto a, const auto b) {
                return a->rewrite_ctx.range.offset < b->rewrite_ctx.range.offset;
        });

        // Collect offset => set(tokens)
        std::vector<std::set<str8_t>> V;

        for (const auto *p = v.data(), *const e = p + v.size(); p != e;)
        {
                const auto idx = (*p)->rewrite_ctx.range.offset;
                std::set<str8_t> S;

		// The first token for an index is the original token (and any other for that index
		// were expanded from that token)
                if (seen.insert((*p)->terms[0].token).second)
                {
                        do
                        {
                                S.insert((*p)->terms[0].token);
                        } while (++p != e && (*p)->rewrite_ctx.range.offset == idx);
                }
                else
                {
                        for (++p; p != e && (*p)->rewrite_ctx.range.offset == idx; ++p)
                                continue;
                }

                V.push_back(std::move(S));
        }

        if (trace)
        {
                for (const auto &it : V)
                {
                        Print("NEXT\n");

                        for (const auto &t : it)
                                Print("\t", t, "\n");
                }
        }

        auto res = Trinity::intersect(0, V, &collection);

        std::sort(res.begin(), res.end(), [](const auto &a, const auto &b) {
                const auto p1 = SwitchBitOps::PopCnt(a.first), p2 = SwitchBitOps::PopCnt(b.first);

                return p2 < p1 || (p2 == p1 && b.second < a.second);
        });

        uint8_t indices[64];
        Buffer b, b2;
        Switch::unordered_map<uint8_t, str8_t> map;
        std::vector<str8_t> tokens;

	// So that we can map original query index => original query token at index
        for (const auto n : originalQuery.nodes())
        {
                if (n->type == ast_node::Type::Token)
                        map.insert({n->p->index, n->p->terms[0].token});
        }

        for (uint32_t i{0}; i != res.size() && i != 5; ++i)
        {
                const auto m = res[i].first;
                const auto cnt = res[i].second;
                const auto n = Trinity::intersection_indices(m, indices);

                if (trace)
                {
                        b.clear();
                        b2.clear();
                        for (uint32_t i{0}; i != n; ++i)
                        {
                                b.append(indices[i], ' ');
                                b2.append(map[indices[i]], ' ');
                        }

                        if (b.size())
                        {
                                b.shrink_by(1);
                                b2.shrink_by(1);
                        }

                        Print("FOR ", b.as_s32(), " [", b2, "] popcnt ", SwitchBitOps::PopCnt(m), " =>", cnt, "\n");
                }
                else
                {
                        tokens.clear();

                        for (uint8_t i{0}; i != n; ++i)
                                tokens.push_back(map[indices[i]]);

                        resp.push_back({{a->CopyOf(tokens.data(), tokens.size()), uint8_t(tokens.size())}, cnt});
                }
        }

        return resp;
}
<commit_msg>Refactor<commit_after>#include "intersect.h"

using namespace Trinity;

void Trinity::intersect_impl(const uint64_t stopwordsMask,
                             const std::vector<std::set<str8_t>> &tokens,
                             IndexSource *__restrict__ const src, masked_documents_registry *const __restrict__ maskedDocumentsRegistry, std::vector<std::pair<uint64_t, uint32_t>> *const out)
{

        static constexpr bool trace{false};
        struct tracked
        {
                Codecs::Decoder *dec;
                uint8_t tokenIdx;
        } remaining[512];

        Dexpect(tokens.size() <= sizeof(uint64_t) << 3);
        Dexpect(out);

        uint64_t origMask{0}; // we don't want to match the original query
        uint16_t rem{0};

        for (uint8_t i{0}; i != tokens.size(); ++i)
        {
                for (const auto &token : tokens[i])
                {
                        if (const auto tctx = src->term_ctx(token); tctx.documents)
                        {
                                auto dec = src->new_postings_decoder(token, tctx);

                                dec->begin();
                                remaining[rem++] = {dec, i};
                                origMask |= uint64_t(1u) << i;

                                if (trace)
                                        SLog("For [", token, "] ", tctx.documents, "\n");
                        }
                        else if (trace)
                                SLog("Unknown for [", token, "]\n");
                }
        }

        if (!rem)
                return;

        struct ctx
        {
                uint64_t mapPrev{0};
                uint8_t indexPrev{0};

                struct match
                {
                        uint64_t v;
                        uint32_t cnt;
                };

                std::vector<match> matches;

                void consider(const uint64_t map)
                {
                        if (map == mapPrev)
                                ++matches[indexPrev].cnt;
                        else
                        {
                                auto matchesCnt = matches.size();
                                auto all = matches.data();

                                mapPrev = map;
                                for (uint8_t i{0}; i < matchesCnt;)
                                {
#if 1
                                        if (const auto v = all[i].v; (v & map) == map)
                                        {
                                                // [wars jedi] [star wars jedi]
                                                if (map == v)
                                                        ++all[i].cnt;
                                                indexPrev = i;
                                                return;
                                        }
                                        else if ((map & v) == v)
                                        {
                                                // [star wars return jedi] [wars jedi]
                                                matches[i] = matches.back();
                                                matches.pop_back();
                                                --matchesCnt;
                                        }
#else
                                        if (all[i].v == map)
                                        {
                                                ++all[i].cnt;
                                                indexPrev = i;
                                                return;
                                        }
#endif
                                        else
                                                ++i;
                                }

                                indexPrev = matchesCnt;
                                matches.push_back({map, 1});
                        }
                }

                void finalize()
                {
                        std::sort(matches.begin(), matches.end(), [](const auto &a, const auto &b) noexcept {
                                const auto r = int8_t(SwitchBitOps::PopCnt(b.v)) - int8_t(SwitchBitOps::PopCnt(a.v));

                                return r < 0 || (!r && b.cnt < a.cnt);
                        });
                }
        };

        uint16_t selected[sizeof_array(remaining)];
        ctx c;
        const auto before = Timings::Microseconds::Tick();

        for (;;)
        {
                uint16_t cnt{1};
                docid_t lowest;
                const auto &it = remaining[0];
                uint64_t mask = uint64_t(1u) << it.tokenIdx;
                uint8_t first{0}, last{0};

                selected[0] = 0;
                lowest = it.dec->curDocument.id;
                for (uint32_t i{1}; i != rem; ++i)
                {
                        const auto &it = remaining[i];

                        // SLog("For [", tokens[it.tokenIdx], "] ", it.dec->curDocument.id, "\n");

                        if (const auto docID = it.dec->curDocument.id; docID == lowest)
                        {
                                const auto m = uint64_t(1u) << it.tokenIdx;

                                mask |= m;
                                selected[cnt++] = i;
                                last = i;
                        }
                        else if (docID < lowest)
                        {
                                mask = uint64_t(1u) << it.tokenIdx;
                                selected[0] = i;
                                cnt = 1;
                                lowest = docID;
                                first = last = i;
                        }

                l100:;
                }

                if (mask != origMask)
                {
                        if (0 == (stopwordsMask & ((uint64_t(1) << first) | (uint64_t(1) << last))))
                        {
                                if (!maskedDocumentsRegistry->test(lowest))
                                        c.consider(mask);
                        }
                }

                while (cnt)
                {
                        const auto idx = selected[--cnt];

                        if (!remaining[idx].dec->next())
                        {
                                delete remaining[idx].dec;
                                if (--rem == 0)
                                        goto l10;
                                else
                                        remaining[idx] = remaining[rem];
                        }
                }
        }

l10:
        c.finalize();
        SLog(duration_repr(Timings::Microseconds::Since(before)), " to intersect, c.matches.size = ", c.matches.size(), "\n");

        for (const auto &it : c.matches)
        {
                if (trace)
                        SLog("output:", it.v, ", cnt = ", it.cnt, ", popcnt = ", SwitchBitOps::PopCnt(it.v), "\n");
                out->push_back({it.v, it.cnt});
        }
}

std::vector<std::pair<uint64_t, uint32_t>> Trinity::intersect(const uint64_t stopwordsMask, const std::vector<std::set<str8_t>> &tokens, IndexSourcesCollection *collection)
{
        std::vector<std::pair<uint64_t, uint32_t>> out;
        const auto n = collection->sources.size();

        // TODO: use std::async()?
        for (uint32_t i{0}; i != n; ++i)
        {
                auto source = collection->sources[i];
                auto scanner = collection->scanner_registry_for(i);

                intersect_impl(stopwordsMask, tokens, source, scanner.get(), &out);
        }

        std::sort(out.begin(), out.end(), [](const auto &a, const auto &b) { return a.first < b.first; });

        auto o = out.data();
        for (const auto *p = out.data(), *const e = p + out.size(); p != e;)
        {
                const auto mask = p->first;
                auto cnt = p->second;

                for (++p; p != e && p->first == mask; ++p)
                        continue;

                *o++ = {mask, cnt};
        }

        out.resize(o - out.data());
        return out;
}

uint8_t Trinity::intersection_indices(uint64_t mask, uint8_t *const out)
{
        uint8_t shift{0}, collected{0};

        do
        {
                auto idx = SwitchBitOps::LeastSignificantBitSet(mask);
                const auto translated = idx + shift - 1;

                out[collected++] = translated;

                mask >>= idx;
                shift += idx;
        } while (mask);

        return collected;
}

std::vector<std::pair<range_base<str8_t *, uint8_t>, std::size_t>> Trinity::intersection_alternatives(const query &originalQuery, query &rewrittenQuery, IndexSourcesCollection &collection, simple_allocator *const a)
{
        static constexpr bool trace{false};
        std::vector<std::pair<range_base<str8_t *, uint8_t>, std::size_t>> resp;

        if (!originalQuery.can_intersect())
                return resp;

        auto &q{rewrittenQuery};

        // This works because Trinity::rewrite_query() sets rewrite_ctx for each token/phrase
        std::vector<Trinity::phrase *> v;
        std::set<str8_t> seen;

        for (const auto n : q.nodes())
        {
                if (n->type == Trinity::ast_node::Type::Token)
                        v.push_back(n->p);
        }

        std::sort(v.begin(), v.end(), [](const auto a, const auto b) {
                return a->rewrite_ctx.range.offset < b->rewrite_ctx.range.offset;
        });

        // Collect offset => set(tokens)
        std::vector<std::set<str8_t>> V;

        for (const auto *p = v.data(), *const e = p + v.size(); p != e;)
        {
                const auto idx = (*p)->rewrite_ctx.range.offset;
                std::set<str8_t> S;

		// The first token for an index is the original token (and any other for that index
		// were expanded from that token)
                if (seen.insert((*p)->terms[0].token).second)
                {
                        do
                        {
                                S.insert((*p)->terms[0].token);
                        } while (++p != e && (*p)->rewrite_ctx.range.offset == idx);
                }
                else
                {
                        for (++p; p != e && (*p)->rewrite_ctx.range.offset == idx; ++p)
                                continue;
                }

                V.push_back(std::move(S));
        }

        if (trace)
        {
                for (const auto &it : V)
                {
                        Print("NEXT\n");

                        for (const auto &t : it)
                                Print("\t", t, "\n");
                }
        }

        auto res = Trinity::intersect(0, V, &collection);

        std::sort(res.begin(), res.end(), [](const auto &a, const auto &b) {
                const auto p1 = SwitchBitOps::PopCnt(a.first), p2 = SwitchBitOps::PopCnt(b.first);

                return p2 < p1 || (p2 == p1 && b.second < a.second);
        });

        uint8_t indices[64];
        Buffer b, b2;
        Switch::unordered_map<uint8_t, str8_t> map;
        std::vector<str8_t> tokens;

	// So that we can map original query index => original query token at index
        for (const auto n : originalQuery.nodes())
        {
                if (n->type == ast_node::Type::Token)
                        map.insert({n->p->index, n->p->terms[0].token});
        }

        for (uint32_t i{0}; i != res.size() && i != 5; ++i)
        {
                const auto m = res[i].first;
                const auto cnt = res[i].second;
                const auto n = Trinity::intersection_indices(m, indices);

                if (trace)
                {
                        b.clear();
                        b2.clear();
                        for (uint32_t i{0}; i != n; ++i)
                        {
                                b.append(indices[i], ' ');
                                b2.append(map[indices[i]], ' ');
                        }

                        if (b.size())
                        {
                                b.shrink_by(1);
                                b2.shrink_by(1);
                        }

                        Print("FOR ", b.AsS32(), " [", b2, "] popcnt ", SwitchBitOps::PopCnt(m), " =>", cnt, "\n");
                }
                else
                {
                        tokens.clear();

                        for (uint8_t i{0}; i != n; ++i)
                                tokens.push_back(map[indices[i]]);

                        resp.push_back({{a->CopyOf(tokens.data(), tokens.size()), uint8_t(tokens.size())}, cnt});
                }
        }

        return resp;
}
<|endoftext|>


<commit_before>#include "PlannerWrapper.hpp"
#include "planning/Path.hpp"

PlannerWrapper::PlannerWrapper()
{
    Eigen::Vector2d size(800, 600);
    statespace_ = std::make_shared<RRT::GridStateSpace>(size.x(), size.y(), 40, 30);
    birrt_ = std::make_unique<RRT::BiRRT<Eigen::Vector2d>>(statespace_, 2);

    //  setup birrt
    birrt_->setStartState(size / 10);
    birrt_->setGoalState(size / 2);
    birrt_->setMaxStepSize(100);
    birrt_->setStepSize(10);
    birrt_->setMaxIterations(1000);
    birrt_->setASCEnabled(true);
    birrt_->setGoalBias(0.2);
    birrt_->setWaypointBias(0.2);
    birrt_->setGoalMaxDist(5);

    start_velocity_ = Eigen::Vector2d(3, 0);
    goal_velocity_ = Eigen::Vector2d(0, 3);
}

void PlannerWrapper::step()
{
    int numTimes = 5;

    for (int i = 0; i < numTimes; i++)
    {
        birrt_->grow();
    }

    ROS_INFO("#%d with size() = %d", birrt_->iterationCount(), birrt_->getPath().size());

    // store solution
    previous_solution_.clear();
    if (birrt_->startSolutionNode() != nullptr)
    {
        ROS_INFO("   Found a solution");
        previous_solution_ = birrt_->getPath();
        RRT::SmoothPath(previous_solution_, *statespace_);
    }
}
<commit_msg>removed ROS_INFO due to errors thrown on CI<commit_after>#include "PlannerWrapper.hpp"
#include "planning/Path.hpp"

PlannerWrapper::PlannerWrapper()
{
    Eigen::Vector2d size(800, 600);
    statespace_ = std::make_shared<RRT::GridStateSpace>(size.x(), size.y(), 40, 30);
    birrt_ = std::make_unique<RRT::BiRRT<Eigen::Vector2d>>(statespace_, 2);

    //  setup birrt
    birrt_->setStartState(size / 10);
    birrt_->setGoalState(size / 2);
    birrt_->setMaxStepSize(100);
    birrt_->setStepSize(10);
    birrt_->setMaxIterations(1000);
    birrt_->setASCEnabled(true);
    birrt_->setGoalBias(0.2);
    birrt_->setWaypointBias(0.2);
    birrt_->setGoalMaxDist(5);

    start_velocity_ = Eigen::Vector2d(3, 0);
    goal_velocity_ = Eigen::Vector2d(0, 3);
}

void PlannerWrapper::step()
{
    int numTimes = 5;

    for (int i = 0; i < numTimes; i++)
    {
        birrt_->grow();
    }

    //ROS_INFO("#%d with size() = %d", birrt_->iterationCount(), birrt_->getPath().size());

    // store solution
    previous_solution_.clear();
    if (birrt_->startSolutionNode() != nullptr)
    {
        //ROS_INFO("   Found a solution");
        previous_solution_ = birrt_->getPath();
        RRT::SmoothPath(previous_solution_, *statespace_);
    }
}
<|endoftext|>


<commit_before>
#include <fstream>
#include <sstream>
#include <string>

#include "drake/Path.h"
#include "drake/thirdParty/tinydir/tinydir.h"
#include "drake/util/drakeGeometryUtil.h"
#include "xmlUtil.h"

using namespace std;
using namespace Eigen;
using namespace tinyxml2;

bool ParseThreeVectorValue(const char* strval, Eigen::Vector3d* val) {
  if (val == nullptr)
    throw std::runtime_error(
        "ERROR: ParseThreeVectorValue: parameter val is nullptr!");
  if (strval) {
    std::stringstream ss(strval);
    // supports a single scalar value or 3-vector value.
    ss >> (*val)[0];
    if (ss.good()) {
      ss >> (*val)[1] >> (*val)[2];
    } else {
      (*val)[1] = (*val)[0];
      (*val)[2] = (*val)[0];
    }
    return true;
  } else {
    return false;
  }
}

bool ParseThreeVectorValue(tinyxml2::XMLElement* node, Eigen::Vector3d* val) {
  if (node)
    return ParseThreeVectorValue(node->FirstChild()->Value(), val);
  else
    return false;
}

bool ParseThreeVectorValue(tinyxml2::XMLElement* node, const char* element_name,
                           Eigen::Vector3d* val) {
  return ParseThreeVectorValue(node->FirstChildElement(element_name), val);
}

bool ParseThreeVectorAttribute(tinyxml2::XMLElement* node,
                               const char* attribute_name,
                               Eigen::Vector3d* val) {
  return ParseThreeVectorValue(node->Attribute(attribute_name), val);
}

// only writes values if they exist
bool parseVectorAttribute(const tinyxml2::XMLElement* node,
                          const char* attribute_name, Eigen::Vector3d& val) {
  const char* attr = node->Attribute(attribute_name);
  if (attr) {
    std::stringstream s(attr);
    s >> val(0) >> val(1) >> val(2);
    return true;
  }
  return false;
}

bool parseVectorAttribute(const tinyxml2::XMLElement* node,
                          const char* attribute_name, Eigen::Vector4d& val) {
  const char* attr = node->Attribute(attribute_name);
  if (attr) {
    std::stringstream s(attr);
    s >> val(0) >> val(1) >> val(2) >> val(3);
    return true;
  }
  return false;
}

bool parseVectorValue(tinyxml2::XMLElement* node, const char* element_name,
                      Eigen::Vector3d& val) {
  XMLElement* elnode = node->FirstChildElement(element_name);
  if (elnode && elnode->FirstChild()) {
    std::stringstream s(elnode->FirstChild()->Value());
    s >> val(0) >> val(1) >> val(2);
    return true;
  }
  return false;
}

bool parseVectorValue(tinyxml2::XMLElement* node, const char* element_name,
                      Eigen::Vector4d& val) {
  XMLElement* elnode = node->FirstChildElement(element_name);
  if (elnode && elnode->FirstChild()) {
    std::stringstream s(elnode->FirstChild()->Value());
    s >> val(0) >> val(1) >> val(2) >> val(3);
    return true;
  }
  return false;
}

bool parseStringValue(tinyxml2::XMLElement* node, const char* element_name,
                      std::string& val) {
  XMLElement* elnode = node->FirstChildElement(element_name);
  if (elnode && elnode->FirstChild()) {
    val = elnode->FirstChild()->Value();
    return true;
  }
  return false;
}

void originAttributesToTransform(tinyxml2::XMLElement* node,
                                 Eigen::Isometry3d& T) {
  Eigen::Vector3d rpy = Eigen::Vector3d::Zero(), xyz = Eigen::Vector3d::Zero();

  parseVectorAttribute(node, "xyz", xyz);
  parseVectorAttribute(node, "rpy", rpy);

  T.matrix() << rpy2rotmat(rpy), xyz, 0, 0, 0, 1;
}

void poseValueToTransform(tinyxml2::XMLElement* node, const PoseMap& pose_map,
                          Eigen::Isometry3d& T,
                          const Eigen::Isometry3d& T_default_frame) {
  Eigen::Vector3d rpy = Eigen::Vector3d::Zero(), xyz = Eigen::Vector3d::Zero();
  const char* strval = node->FirstChild()->Value();
  if (strval) {
    std::stringstream s(strval);
    s >> xyz(0) >> xyz(1) >> xyz(2) >> rpy(0) >> rpy(1) >> rpy(2);
  }

  T.matrix() << rpy2rotmat(rpy), xyz, 0, 0, 0, 1;

  const char* attr = node->Attribute("frame");
  if (attr && strlen(attr) > 0) {
    std::string frame;
    std::stringstream s(attr);
    s >> frame;
    assert(0 && "this has not been tested yet");  // and could cause problems
                                                  // with the default pose
                                                  // assumptions in the sdf
                                                  // parser, which I simply had
                                                  // to guess
    Eigen::Isometry3d T_frame =
        pose_map.at(frame);  // will throw an exception if the frame is not
                             // found.  that is the desired behavior.
    T = T_frame * T;
  } else {
    T = T_default_frame * T;
  }
}

namespace {
void searchDirectory(map<string, string>& package_map, string path) {
#if defined(WIN32) || defined(WIN64)
  const char pathsep = ';';
#else
  const char pathsep = ':';
#endif

  string token, t;
  istringstream iss(path);
  const std::string target_filename("package.xml");

  while (getline(iss, token, pathsep)) {
    tinydir_dir dir;
    if (tinydir_open(&dir, token.c_str()) < 0) {
      std::cerr << "Unable to open directory: " << token << std::endl;
      continue;
    }

    while (dir.has_next) {
      tinydir_file file;
      tinydir_readfile(&dir, &file);

      // Skip hidden directories (including, importantly, "." and "..").
      if (file.is_dir && (file.name[0] != '.')) {
        searchDirectory(package_map, file.path);
      } else if (file.name == target_filename) {
        spruce::path mypath_s(file.path);
        auto path_split = mypath_s.split();
        if (path_split.size() > 2) {
          string package = path_split.at(path_split.size() - 2);
          auto package_iter = package_map.find(package);
          // Don't overwrite entries in the map
          if (package_iter == package_map.end()) {
            package_map.insert(make_pair(package, mypath_s.root().append("/")));
          }
        }
      }
      tinydir_next(&dir);
    }
    tinydir_close(&dir);
  }
}
}

void populatePackageMap(map<string, string>& package_map) {
  searchDirectory(package_map, Drake::getDrakePath());

  char* cstrpath = getenv("ROS_ROOT");
  if (cstrpath) searchDirectory(package_map, cstrpath);

  cstrpath = getenv("ROS_PACKAGE_PATH");
  if (cstrpath) searchDirectory(package_map, cstrpath);
}

namespace {
bool rospack(const string& package, const map<string, string>& package_map,
             string& package_path) {
  // my own quick and dirty implementation of the rospack algorithm (based on my
  // matlab version in rospack.m)
  auto iter = package_map.find(package);
  if (iter != package_map.end()) {
    package_path = iter->second;
    return true;
  } else {
    cerr << "Warning: Couldn't find package '" << package
         << "' in ROS_ROOT, ROS_PACKAGE_PATH, or user supplied package map"
         << endl;
    return false;
  }
}
}

string resolveFilename(const string& filename,
                       const map<string, string>& package_map,
                       const string& root_dir) {
  spruce::path mesh_filename_s;
  spruce::path raw_filename_s(filename);

  auto split_filename = raw_filename_s.split();

  if (split_filename.front() == "package:") {
    string package_path_string;
    if (rospack(split_filename.at(2), package_map, package_path_string)) {
      spruce::path package_path_s = spruce::path(package_path_string);
      mesh_filename_s = package_path_s;

      auto split_raw = raw_filename_s.split();
      for (int i = 1; i < split_raw.size() - 2; ++i) {
        mesh_filename_s.append(split_raw.at(i + 2));
      }
    } else {
      cerr << "Warning: Mesh '" << filename
           << "' could not be resolved and will be ignored by Drake." << endl;
      return string();
    }
  } else {
    std::string normalized_root_dir = spruce::path(root_dir).getStr();

// if root_dir is a relative path then convert it to absolute
#ifdef _WIN32
    bool dirIsRelative = !(normalized_root_dir.size() >= 2 &&
                           std::isalpha(normalized_root_dir[0]) &&
                           normalized_root_dir[1] == ':');
#else
    bool dirIsRelative =
        !(normalized_root_dir.size() >= 1 && normalized_root_dir[0] == '/');
#endif
    if (dirIsRelative) {
      mesh_filename_s = spruce::path();
      mesh_filename_s.setAsCurrent();
      mesh_filename_s.append(normalized_root_dir);
    } else {
      mesh_filename_s = spruce::path(normalized_root_dir);
    }

    mesh_filename_s.append(filename);
  }
  if (!mesh_filename_s.exists()) {
    cerr << "Warning: File '" << mesh_filename_s.getStr()
         << "' could not be found." << endl;
    cerr << "Warning: Mesh '" << filename
         << "' could not be resolved and will be ignored by Drake." << endl;
    return string();
  }
  return mesh_filename_s.getStr();
}
<commit_msg>Added curley braces. Fixed punctuation in comment.<commit_after>
#include <fstream>
#include <sstream>
#include <string>

#include "drake/Path.h"
#include "drake/thirdParty/tinydir/tinydir.h"
#include "drake/util/drakeGeometryUtil.h"
#include "xmlUtil.h"

using namespace std;
using namespace Eigen;
using namespace tinyxml2;

bool ParseThreeVectorValue(const char* strval, Eigen::Vector3d* val) {
  if (val == nullptr) {
    throw std::runtime_error(
        "ERROR: ParseThreeVectorValue: parameter val is nullptr!");
  }
  if (strval) {
    std::stringstream ss(strval);
    // Supports a single scalar value or 3-vector value.
    ss >> (*val)[0];
    if (ss.good()) {
      ss >> (*val)[1] >> (*val)[2];
    } else {
      (*val)[1] = (*val)[0];
      (*val)[2] = (*val)[0];
    }
    return true;
  } else {
    return false;
  }
}

bool ParseThreeVectorValue(tinyxml2::XMLElement* node, Eigen::Vector3d* val) {
  if (node)
    return ParseThreeVectorValue(node->FirstChild()->Value(), val);
  else
    return false;
}

bool ParseThreeVectorValue(tinyxml2::XMLElement* node, const char* element_name,
                           Eigen::Vector3d* val) {
  return ParseThreeVectorValue(node->FirstChildElement(element_name), val);
}

bool ParseThreeVectorAttribute(tinyxml2::XMLElement* node,
                               const char* attribute_name,
                               Eigen::Vector3d* val) {
  return ParseThreeVectorValue(node->Attribute(attribute_name), val);
}

// only writes values if they exist
bool parseVectorAttribute(const tinyxml2::XMLElement* node,
                          const char* attribute_name, Eigen::Vector3d& val) {
  const char* attr = node->Attribute(attribute_name);
  if (attr) {
    std::stringstream s(attr);
    s >> val(0) >> val(1) >> val(2);
    return true;
  }
  return false;
}

bool parseVectorAttribute(const tinyxml2::XMLElement* node,
                          const char* attribute_name, Eigen::Vector4d& val) {
  const char* attr = node->Attribute(attribute_name);
  if (attr) {
    std::stringstream s(attr);
    s >> val(0) >> val(1) >> val(2) >> val(3);
    return true;
  }
  return false;
}

bool parseVectorValue(tinyxml2::XMLElement* node, const char* element_name,
                      Eigen::Vector3d& val) {
  XMLElement* elnode = node->FirstChildElement(element_name);
  if (elnode && elnode->FirstChild()) {
    std::stringstream s(elnode->FirstChild()->Value());
    s >> val(0) >> val(1) >> val(2);
    return true;
  }
  return false;
}

bool parseVectorValue(tinyxml2::XMLElement* node, const char* element_name,
                      Eigen::Vector4d& val) {
  XMLElement* elnode = node->FirstChildElement(element_name);
  if (elnode && elnode->FirstChild()) {
    std::stringstream s(elnode->FirstChild()->Value());
    s >> val(0) >> val(1) >> val(2) >> val(3);
    return true;
  }
  return false;
}

bool parseStringValue(tinyxml2::XMLElement* node, const char* element_name,
                      std::string& val) {
  XMLElement* elnode = node->FirstChildElement(element_name);
  if (elnode && elnode->FirstChild()) {
    val = elnode->FirstChild()->Value();
    return true;
  }
  return false;
}

void originAttributesToTransform(tinyxml2::XMLElement* node,
                                 Eigen::Isometry3d& T) {
  Eigen::Vector3d rpy = Eigen::Vector3d::Zero(), xyz = Eigen::Vector3d::Zero();

  parseVectorAttribute(node, "xyz", xyz);
  parseVectorAttribute(node, "rpy", rpy);

  T.matrix() << rpy2rotmat(rpy), xyz, 0, 0, 0, 1;
}

void poseValueToTransform(tinyxml2::XMLElement* node, const PoseMap& pose_map,
                          Eigen::Isometry3d& T,
                          const Eigen::Isometry3d& T_default_frame) {
  Eigen::Vector3d rpy = Eigen::Vector3d::Zero(), xyz = Eigen::Vector3d::Zero();
  const char* strval = node->FirstChild()->Value();
  if (strval) {
    std::stringstream s(strval);
    s >> xyz(0) >> xyz(1) >> xyz(2) >> rpy(0) >> rpy(1) >> rpy(2);
  }

  T.matrix() << rpy2rotmat(rpy), xyz, 0, 0, 0, 1;

  const char* attr = node->Attribute("frame");
  if (attr && strlen(attr) > 0) {
    std::string frame;
    std::stringstream s(attr);
    s >> frame;
    assert(0 && "this has not been tested yet");  // and could cause problems
                                                  // with the default pose
                                                  // assumptions in the sdf
                                                  // parser, which I simply had
                                                  // to guess
    Eigen::Isometry3d T_frame =
        pose_map.at(frame);  // will throw an exception if the frame is not
                             // found.  that is the desired behavior.
    T = T_frame * T;
  } else {
    T = T_default_frame * T;
  }
}

namespace {
void searchDirectory(map<string, string>& package_map, string path) {
#if defined(WIN32) || defined(WIN64)
  const char pathsep = ';';
#else
  const char pathsep = ':';
#endif

  string token, t;
  istringstream iss(path);
  const std::string target_filename("package.xml");

  while (getline(iss, token, pathsep)) {
    tinydir_dir dir;
    if (tinydir_open(&dir, token.c_str()) < 0) {
      std::cerr << "Unable to open directory: " << token << std::endl;
      continue;
    }

    while (dir.has_next) {
      tinydir_file file;
      tinydir_readfile(&dir, &file);

      // Skip hidden directories (including, importantly, "." and "..").
      if (file.is_dir && (file.name[0] != '.')) {
        searchDirectory(package_map, file.path);
      } else if (file.name == target_filename) {
        spruce::path mypath_s(file.path);
        auto path_split = mypath_s.split();
        if (path_split.size() > 2) {
          string package = path_split.at(path_split.size() - 2);
          auto package_iter = package_map.find(package);
          // Don't overwrite entries in the map
          if (package_iter == package_map.end()) {
            package_map.insert(make_pair(package, mypath_s.root().append("/")));
          }
        }
      }
      tinydir_next(&dir);
    }
    tinydir_close(&dir);
  }
}
}

void populatePackageMap(map<string, string>& package_map) {
  searchDirectory(package_map, Drake::getDrakePath());

  char* cstrpath = getenv("ROS_ROOT");
  if (cstrpath) searchDirectory(package_map, cstrpath);

  cstrpath = getenv("ROS_PACKAGE_PATH");
  if (cstrpath) searchDirectory(package_map, cstrpath);
}

namespace {
bool rospack(const string& package, const map<string, string>& package_map,
             string& package_path) {
  // my own quick and dirty implementation of the rospack algorithm (based on my
  // matlab version in rospack.m)
  auto iter = package_map.find(package);
  if (iter != package_map.end()) {
    package_path = iter->second;
    return true;
  } else {
    cerr << "Warning: Couldn't find package '" << package
         << "' in ROS_ROOT, ROS_PACKAGE_PATH, or user supplied package map"
         << endl;
    return false;
  }
}
}

string resolveFilename(const string& filename,
                       const map<string, string>& package_map,
                       const string& root_dir) {
  spruce::path mesh_filename_s;
  spruce::path raw_filename_s(filename);

  auto split_filename = raw_filename_s.split();

  if (split_filename.front() == "package:") {
    string package_path_string;
    if (rospack(split_filename.at(2), package_map, package_path_string)) {
      spruce::path package_path_s = spruce::path(package_path_string);
      mesh_filename_s = package_path_s;

      auto split_raw = raw_filename_s.split();
      for (int i = 1; i < split_raw.size() - 2; ++i) {
        mesh_filename_s.append(split_raw.at(i + 2));
      }
    } else {
      cerr << "Warning: Mesh '" << filename
           << "' could not be resolved and will be ignored by Drake." << endl;
      return string();
    }
  } else {
    std::string normalized_root_dir = spruce::path(root_dir).getStr();

// if root_dir is a relative path then convert it to absolute
#ifdef _WIN32
    bool dirIsRelative = !(normalized_root_dir.size() >= 2 &&
                           std::isalpha(normalized_root_dir[0]) &&
                           normalized_root_dir[1] == ':');
#else
    bool dirIsRelative =
        !(normalized_root_dir.size() >= 1 && normalized_root_dir[0] == '/');
#endif
    if (dirIsRelative) {
      mesh_filename_s = spruce::path();
      mesh_filename_s.setAsCurrent();
      mesh_filename_s.append(normalized_root_dir);
    } else {
      mesh_filename_s = spruce::path(normalized_root_dir);
    }

    mesh_filename_s.append(filename);
  }
  if (!mesh_filename_s.exists()) {
    cerr << "Warning: File '" << mesh_filename_s.getStr()
         << "' could not be found." << endl;
    cerr << "Warning: Mesh '" << filename
         << "' could not be resolved and will be ignored by Drake." << endl;
    return string();
  }
  return mesh_filename_s.getStr();
}
<|endoftext|>


<commit_before><commit_msg>fix last commit<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SlsPageObjectViewContact.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: kz $ $Date: 2008-04-03 14:39:44 $
 *
 *  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 SD_SLIDESORTER_PAGE_OBJECT_VIEW_CONTACT_HXX
#define SD_SLIDESORTER_PAGE_OBJECT_VIEW_CONTACT_HXX

#include "model/SlsSharedPageDescriptor.hxx"
#include <svx/sdtakitm.hxx>
#include <svx/sdr/contact/viewcontactofpageobj.hxx>

class SdrPageObj;

namespace sdr {namespace contact {
class ViewObjectContact;
class ObjectContact;
} }

namespace sd { namespace slidesorter { namespace view {

/** Details:
    This class has to provide the bounding box but can not determine it
    fully because it has no access to the output device.  It therefore
    retrieves some of the necessary data, the border, from the
    PageDescriptor which acts here as persistent storage.
*/
class PageObjectViewContact
    : public ::sdr::contact::ViewContactOfPageObj
{
public:
    PageObjectViewContact (
        SdrPageObj& rPageObj,
        const model::SharedPageDescriptor& rpDescriptor);
    ~PageObjectViewContact (void);

    /** Create a ViewObjectContact object that buffers its output in a
        bitmap.
        @return
            Ownership of the new object passes to the caller.
    */
    virtual ::sdr::contact::ViewObjectContact&
        CreateObjectSpecificViewObjectContact(
            ::sdr::contact::ObjectContact& rObjectContact);

    const SdrPage* GetPage (void) const;

    SdrPageObj& GetPageObject (void) const;

    Rectangle GetPageObjectBoundingBox (void) const;

    /** Return the original bounding box of the page objects, not the
        enlarged rectangle that encloses the frames, indicators, and the
        title (as returned by GetPaintRectangle()).
    */
    virtual Rectangle GetPageRectangle (void);

    virtual void ActionChanged (void);

protected:
    /** Enlarge the paint rectangle of the base class by the space that is
        used to paint the focus and selection indicators, the fade effect
        indicator, and the slide name.
    */
    virtual void CalcPaintRectangle (void);

    virtual void PrepareDelete (void);

private:
    // The bounding box that is calculated by the base class implementation
    // of the CalcPaintRectangle() method.
    Rectangle maPageObjectBoundingBox;

    /** This flag is set as long as PrepareDelete() has not been called.
    */
    bool mbIsValid;

    model::SharedPageDescriptor mpDescriptor;
};

} } } // end of namespace ::sd::slidesorter::view

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.6.234); FILE MERGED 2008/03/31 13:58:53 rt 1.6.234.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: SlsPageObjectViewContact.hxx,v $
 * $Revision: 1.8 $
 *
 * 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 SD_SLIDESORTER_PAGE_OBJECT_VIEW_CONTACT_HXX
#define SD_SLIDESORTER_PAGE_OBJECT_VIEW_CONTACT_HXX

#include "model/SlsSharedPageDescriptor.hxx"
#include <svx/sdtakitm.hxx>
#include <svx/sdr/contact/viewcontactofpageobj.hxx>

class SdrPageObj;

namespace sdr {namespace contact {
class ViewObjectContact;
class ObjectContact;
} }

namespace sd { namespace slidesorter { namespace view {

/** Details:
    This class has to provide the bounding box but can not determine it
    fully because it has no access to the output device.  It therefore
    retrieves some of the necessary data, the border, from the
    PageDescriptor which acts here as persistent storage.
*/
class PageObjectViewContact
    : public ::sdr::contact::ViewContactOfPageObj
{
public:
    PageObjectViewContact (
        SdrPageObj& rPageObj,
        const model::SharedPageDescriptor& rpDescriptor);
    ~PageObjectViewContact (void);

    /** Create a ViewObjectContact object that buffers its output in a
        bitmap.
        @return
            Ownership of the new object passes to the caller.
    */
    virtual ::sdr::contact::ViewObjectContact&
        CreateObjectSpecificViewObjectContact(
            ::sdr::contact::ObjectContact& rObjectContact);

    const SdrPage* GetPage (void) const;

    SdrPageObj& GetPageObject (void) const;

    Rectangle GetPageObjectBoundingBox (void) const;

    /** Return the original bounding box of the page objects, not the
        enlarged rectangle that encloses the frames, indicators, and the
        title (as returned by GetPaintRectangle()).
    */
    virtual Rectangle GetPageRectangle (void);

    virtual void ActionChanged (void);

protected:
    /** Enlarge the paint rectangle of the base class by the space that is
        used to paint the focus and selection indicators, the fade effect
        indicator, and the slide name.
    */
    virtual void CalcPaintRectangle (void);

    virtual void PrepareDelete (void);

private:
    // The bounding box that is calculated by the base class implementation
    // of the CalcPaintRectangle() method.
    Rectangle maPageObjectBoundingBox;

    /** This flag is set as long as PrepareDelete() has not been called.
    */
    bool mbIsValid;

    model::SharedPageDescriptor mpDescriptor;
};

} } } // end of namespace ::sd::slidesorter::view

#endif
<|endoftext|>


<commit_before>#ifndef ATOMS_H
#define ATOMS_H
#include<string>
#include<iostream>
#include<map>
#include<boost/shared_ptr.hpp>
#include"heaps.hpp"

class Atom {
protected:
	Atom(){};
	Atom(Atom&){};
public:
	virtual ~Atom(){};
};

class Globals;

class GlobalAtom : public Atom {
private:
	std::string utf8string;
	Generic* value;
public:
	GlobalAtom(std::string& s) : utf8string(s), value(NULL){};
	virtual ~GlobalAtom(){};
	void emit(void) const {
		std::cout << utf8string;
	};
	friend class Globals;
};

/*from (uniq)*/
class LocalAtom : public Atom {
public:
	virtual ~LocalAtom(){};
};

class Globals : public Heap {
private:
	std::map< std::string, boost::shared_ptr<Atom> > string_to_atom;
	/*insert mutex here*/
	/*The mutex must be locked for the following cases:
	1. Setting of global variables
	2. Garbage collection.  1 & 2 will probably need to be done
	   right after one another.
	3. Actual reading of variable (if variable is not in cache)
	*/
protected:
	virtual void get_root_set(std::stack<Generic**>&);
public:
	boost::shared_ptr<Atom> lookup(std::string& s){
		/*insert locking of string_to_atom table here*/
		std::map< std::string, boost::shared_ptr<Atom> >::iterator i;
		i = string_to_atom.find(s);
		if(i != string_to_atom.end()){
			std::map< std::string,
				boost::shared_ptr<Atom> >::value_type v = *i;
			return v.second;
		} else {
			boost::shared_ptr<Atom> tmp(new GlobalAtom(s));
			string_to_atom[s].swap(tmp);
			return string_to_atom[s];
		}
	}
	boost::shared_ptr<Atom> lookup(char const * s){
		std::string ss(s);
		return lookup(ss);
	}
	/*precondition: lock for this object must be acquired*/
	void assign(boost::shared_ptr<Atom> a,
		    boost::shared_ptr<Semispace> ns,
		    Generic* g){
		other_spaces.push_back(ns);
		GlobalAtom* gp = dynamic_cast<GlobalAtom*>(&*a);
		if(gp == NULL) throw std::runtime_error("write to non-global");
		gp->value = g;
	}
	void GC(void){Heap::GC(0);};
	virtual ~Globals(){};
};

#endif //ATOMS_H

<commit_msg>Added <stdexcept> header<commit_after>#ifndef ATOMS_H
#define ATOMS_H
#include<string>
#include<iostream>
#include<map>
#include<boost/shared_ptr.hpp>
#include<stdexcept>
#include"heaps.hpp"

class Atom {
protected:
	Atom(){};
	Atom(Atom&){};
public:
	virtual ~Atom(){};
};

class Globals;

class GlobalAtom : public Atom {
private:
	std::string utf8string;
	Generic* value;
public:
	GlobalAtom(std::string& s) : utf8string(s), value(NULL){};
	virtual ~GlobalAtom(){};
	void emit(void) const {
		std::cout << utf8string;
	};
	friend class Globals;
};

/*from (uniq)*/
class LocalAtom : public Atom {
public:
	virtual ~LocalAtom(){};
};

class Globals : public Heap {
private:
	std::map< std::string, boost::shared_ptr<Atom> > string_to_atom;
	/*insert mutex here*/
	/*The mutex must be locked for the following cases:
	1. Setting of global variables
	2. Garbage collection.  1 & 2 will probably need to be done
	   right after one another.
	3. Actual reading of variable (if variable is not in cache)
	*/
protected:
	virtual void get_root_set(std::stack<Generic**>&);
public:
	boost::shared_ptr<Atom> lookup(std::string& s){
		/*insert locking of string_to_atom table here*/
		std::map< std::string, boost::shared_ptr<Atom> >::iterator i;
		i = string_to_atom.find(s);
		if(i != string_to_atom.end()){
			std::map< std::string,
				boost::shared_ptr<Atom> >::value_type v = *i;
			return v.second;
		} else {
			boost::shared_ptr<Atom> tmp(new GlobalAtom(s));
			string_to_atom[s].swap(tmp);
			return string_to_atom[s];
		}
	}
	boost::shared_ptr<Atom> lookup(char const * s){
		std::string ss(s);
		return lookup(ss);
	}
	/*precondition: lock for this object must be acquired*/
	void assign(boost::shared_ptr<Atom> a,
		    boost::shared_ptr<Semispace> ns,
		    Generic* g){
		other_spaces.push_back(ns);
		GlobalAtom* gp = dynamic_cast<GlobalAtom*>(&*a);
		if(gp == NULL) throw std::runtime_error("write to non-global");
		gp->value = g;
	}
	void GC(void){Heap::GC(0);};
	virtual ~Globals(){};
};

#endif //ATOMS_H

<|endoftext|>


<commit_before>#ifndef TYPES_H
#define TYPES_H
#include<stack>
#include<set>
#include<vector>
#include"heaps.hpp"
#include"hashes.hpp"
#include"variables.hpp"
#include"executors.hpp"

class Semispace;
void* operator new(size_t, Semispace&);
void operator delete(void*, Semispace&);

class ToPointerLock;

class Generic {
private:
	Generic* to_pointer;
protected:
	Generic(void) : to_pointer(NULL) {};
	Generic(Generic const&) : to_pointer(NULL) {};
public:
	friend class Semispace;
	friend class ToPointerLock;

	/*hash should return pretty much just any
	size_t, provided that an unmutated copy of
	that object will have the same hash().
	There is NO NEED TO PROPERLY DISTRIBUTE BITS,
	and it would probably be better not to: the
	table lookup function will use several int-
	to-int hashing functions for the bloom
	filter.
	*/
	virtual size_t hash(void) const =0;
	virtual Generic* clone(Semispace&) const =0;
	/* clone should always have the following code:
	virtual Type* clone(Semispace& sp) const{
		return new(sp) Type(*this);
	}
	*/

	/*gets addresses of references to other objects*/
	virtual void get_refs(std::stack<Generic**>&){};

	/*comparisons*/
	virtual bool is(Generic const* gp) const{return gp == this;}
	virtual bool iso(Generic const* gp) const{return is(gp);}

	virtual size_t get_size(void) const =0;
	/*get_size should always have the following code:
	virtual size_t get_size(void) const {
		return sizeof(Type);
	}
	*/

	/*symbols should change this to check that it's nil*/
	virtual bool isnil(void) const {return 0;};
	bool istrue(void) const {return !isnil();};

	virtual void probe(size_t indent) =0;//for debugging

	virtual ~Generic(){};

	size_t total_size(ToPointerLock&, std::stack<Generic**>&);
};

inline bool is(Generic const* a, Generic const* b){ return a->is(b);}
inline bool iso(Generic const* a, Generic const* b){ return a->iso(b);}

/*RAII class to handle the to-pointers
This is used to protect the to-pointers in case of
an exception.  The invariant is, to-pointers are
NULL during normal operation.  If to-pointers must
be used, access to them should be via
ToPointerLock's, so that the to-pointers are reset
to NULL once the non-normal operation (GC,
tracing) are complete.  When the operation
determines that the to-pointers can be left used
(i.e. after a GC run) then it can call the clear()
member function so that it won't bother resetting
the to-pointers.
*/
class ToPointerLock{
private:
	std::set<Generic*> enset;
public:
	void pointto(Generic* from, Generic* to){
		enset.insert(from);
		from->to_pointer = to;
	}
	Generic* to(Generic* from){
		return from->to_pointer;
	}
	/*used to ignore the to-pointers in a successful
	copy-and-sweep GC cycle
	*/
	void good(void){
		enset.clear();
	}
	~ToPointerLock(){
		std::set<Generic*>::iterator i;
		for(i = enset.begin(); i != enset.end(); ++i){
			(*i)->to_pointer = NULL;
		}
	}
};

class Cons : public Generic{
protected:
	Cons(Cons const& s) : Generic(), a(s.a), d(s.d){};
public:
	Generic* a;
	Generic* d;
	/*standard stuff*/
	virtual size_t hash(void) const {
		return a->hash() ^ d->hash();
	}
	virtual Cons* clone(Semispace& sp) const{
		return new(sp) Cons(*this);
	}
	virtual size_t get_size(void) const {
		return sizeof(Cons);
	}

	/*comparisons*/
	virtual bool iso(Generic*gp) const{
		if(is(gp)) {
			return 1;
		} else {
			Cons* cp = dynamic_cast<Cons*>(gp);
			if(cp != NULL){
				return a->iso(cp->a) && d->iso(cp->d);
			} else return 0;
		}
	}

	/*references*/
	virtual void get_refs(std::stack<Generic**>&s){
		s.push(&a);
		s.push(&d);
	}

	virtual void probe(size_t);

	Cons(void) : Generic() {};
	virtual ~Cons(){};

};

class MetadataCons : public Cons {
protected:
	MetadataCons(MetadataCons const& s):Cons(s), line(s.line), file(s.file){};
public:
	Generic* line;
	Generic* file;
	virtual MetadataCons* clone(Semispace& sp) const{
		return new(sp) MetadataCons(*this);
	}
	virtual size_t get_size(void) const {
		return sizeof(MetadataCons);
	}
	virtual void get_refs(std::stack<Generic**>& s){
		Cons::get_refs(s);
		s.push(&line);
		s.push(&file);
	}

	virtual void probe(size_t);

	MetadataCons() : Cons() {};
	virtual ~MetadataCons(){};

};

class Sym : public Generic{
private:
	Sym(void){}; //disallowed!
protected:
	Sym(Sym const& s) : Generic(), a(s.a){};
public:
	/*standard stuff*/
	virtual size_t hash(void) const{
		return (size_t) &(*a);
	}
	virtual Sym* clone(Semispace& sp) const{
		return new(sp) Sym(*this);
	}
	virtual size_t get_size(void) const{
		return sizeof(Sym);
	};

	virtual bool is(Generic* gp) const{
		if(gp == this) return 1;
		Sym* sp = dynamic_cast<Sym*>(gp);
		if(sp != NULL){
			return sp->a == a;
		} else return 0;
	};

	virtual bool isnil(void) const {
		return a == NILATOM;
	}

	virtual void probe(size_t);

	Sym(boost::shared_ptr<Atom> const& na) : Generic(), a(na){};
	virtual ~Sym(){};

	/*new stuff*/
	Atom& atom(void){return *a;};
	boost::shared_ptr<Atom> a;
};

class Executor;

class Closure : public Generic {
private:
	boost::shared_ptr<Executor> cd;
	/*possibly add a parallel vector of variable name atoms for
	debugging?
	*/
	std::vector<Generic*> vars;
protected:
	Closure(Closure const& o) : Generic(), cd(o.cd), vars(o.vars) {}
public:
	/*standard stuff*/
	virtual size_t hash(void) const{
		return (size_t) &*cd;
	}
	virtual Closure* clone(Semispace& sp) const{
		return new(sp) Closure(*this);
	}
	virtual size_t get_size(void) const{
		return sizeof(Closure);
	}

	virtual void get_refs(std::stack<Generic**>& s){
		for(size_t i = 0; i < vars.size(); ++i){
			s.push(&vars[i]);
		}
	}

	virtual void probe(size_t);

	Closure(Executor* c, size_t s) :
		Generic(), cd(c), vars(s) {};

	/*new stuff*/
	Executor const& code(void) {return *cd;};
	/*WARNING
	arc2c references closure values starting at index 1 (index 0
	is the function's code itself, and is never used in practice).
	We will have to translate the numbers properly for those cases
	*/
	Generic* & operator[](int i) {return vars[i];}
	Generic* const & operator[](int i) const {return vars[i];}
};

class Integer : public Generic {
private:
	int val;
protected:
	Integer(Integer const& o) : Generic(), val(o.val){}
public:
	/*standard stuff*/
	virtual size_t hash() const {
		return (size_t) val;
	}
	virtual Integer clone(Semispace& sp) const{
		return new(sp) Integer(*this);
	}
	virtual size_t get_size(void) const{
		return sizeof(Integer);
	}

	virtual void probe(size_t);

	/*new stuff*/
	int integer(void){return val;}
	Integer(int x) : Generic(), val(x) {}
};

/*Used during compilation to hold a bytecode sequence while
converting from a symbolcode list to an internal bytecode
format.
*/
class ArcBytecodeSequence : public Generic {
protected:
	ArcBytecodeSequence(ArcBytecodeSequence const & o)
		: Generic(), seq(o.seq) {}
public:
	/*standard stuff*/
	virtual size_t hash() const{
		return (size_t)(void*) &*seq;
	}
	virtual ArcBytecodeSequence clone(Semispace& sp) const{
		return new(sp) ArcBytecodeSequence(*this);
	}
	virtual size_t get_size(void) const{
		return sizeof(ArcBytecodeSequence);
	}

	/*new stuff*/
	void append(Bytecode* b){
		seq->append(b);
	}
	boost::shared_ptr<BytecodeSequence> seq;
	ArcBytecodeSequence(void) : Generic(), seq(new BytecodeSequence()) {}
};

#endif //TYPES_H

<commit_msg>Corrected return types of clone() members, added probe() member for ArcBytecodeSequence<commit_after>#ifndef TYPES_H
#define TYPES_H
#include<stack>
#include<set>
#include<vector>
#include"heaps.hpp"
#include"hashes.hpp"
#include"variables.hpp"
#include"executors.hpp"

class Semispace;
void* operator new(size_t, Semispace&);
void operator delete(void*, Semispace&);

class ToPointerLock;

class Generic {
private:
	Generic* to_pointer;
protected:
	Generic(void) : to_pointer(NULL) {};
	Generic(Generic const&) : to_pointer(NULL) {};
public:
	friend class Semispace;
	friend class ToPointerLock;

	/*hash should return pretty much just any
	size_t, provided that an unmutated copy of
	that object will have the same hash().
	There is NO NEED TO PROPERLY DISTRIBUTE BITS,
	and it would probably be better not to: the
	table lookup function will use several int-
	to-int hashing functions for the bloom
	filter.
	*/
	virtual size_t hash(void) const =0;
	virtual Generic* clone(Semispace&) const =0;
	/* clone should always have the following code:
	virtual Type* clone(Semispace& sp) const{
		return new(sp) Type(*this);
	}
	*/

	/*gets addresses of references to other objects*/
	virtual void get_refs(std::stack<Generic**>&){};

	/*comparisons*/
	virtual bool is(Generic const* gp) const{return gp == this;}
	virtual bool iso(Generic const* gp) const{return is(gp);}

	virtual size_t get_size(void) const =0;
	/*get_size should always have the following code:
	virtual size_t get_size(void) const {
		return sizeof(Type);
	}
	*/

	/*symbols should change this to check that it's nil*/
	virtual bool isnil(void) const {return 0;};
	bool istrue(void) const {return !isnil();};

	virtual void probe(size_t indent) =0;//for debugging

	virtual ~Generic(){};

	size_t total_size(ToPointerLock&, std::stack<Generic**>&);
};

inline bool is(Generic const* a, Generic const* b){ return a->is(b);}
inline bool iso(Generic const* a, Generic const* b){ return a->iso(b);}

/*RAII class to handle the to-pointers
This is used to protect the to-pointers in case of
an exception.  The invariant is, to-pointers are
NULL during normal operation.  If to-pointers must
be used, access to them should be via
ToPointerLock's, so that the to-pointers are reset
to NULL once the non-normal operation (GC,
tracing) are complete.  When the operation
determines that the to-pointers can be left used
(i.e. after a GC run) then it can call the clear()
member function so that it won't bother resetting
the to-pointers.
*/
class ToPointerLock{
private:
	std::set<Generic*> enset;
public:
	void pointto(Generic* from, Generic* to){
		enset.insert(from);
		from->to_pointer = to;
	}
	Generic* to(Generic* from){
		return from->to_pointer;
	}
	/*used to ignore the to-pointers in a successful
	copy-and-sweep GC cycle
	*/
	void good(void){
		enset.clear();
	}
	~ToPointerLock(){
		std::set<Generic*>::iterator i;
		for(i = enset.begin(); i != enset.end(); ++i){
			(*i)->to_pointer = NULL;
		}
	}
};

class Cons : public Generic{
protected:
	Cons(Cons const& s) : Generic(), a(s.a), d(s.d){};
public:
	Generic* a;
	Generic* d;
	/*standard stuff*/
	virtual size_t hash(void) const {
		return a->hash() ^ d->hash();
	}
	virtual Cons* clone(Semispace& sp) const{
		return new(sp) Cons(*this);
	}
	virtual size_t get_size(void) const {
		return sizeof(Cons);
	}

	/*comparisons*/
	virtual bool iso(Generic*gp) const{
		if(is(gp)) {
			return 1;
		} else {
			Cons* cp = dynamic_cast<Cons*>(gp);
			if(cp != NULL){
				return a->iso(cp->a) && d->iso(cp->d);
			} else return 0;
		}
	}

	/*references*/
	virtual void get_refs(std::stack<Generic**>&s){
		s.push(&a);
		s.push(&d);
	}

	virtual void probe(size_t);

	Cons(void) : Generic() {};
	virtual ~Cons(){};

};

class MetadataCons : public Cons {
protected:
	MetadataCons(MetadataCons const& s):Cons(s), line(s.line), file(s.file){};
public:
	Generic* line;
	Generic* file;
	virtual MetadataCons* clone(Semispace& sp) const{
		return new(sp) MetadataCons(*this);
	}
	virtual size_t get_size(void) const {
		return sizeof(MetadataCons);
	}
	virtual void get_refs(std::stack<Generic**>& s){
		Cons::get_refs(s);
		s.push(&line);
		s.push(&file);
	}

	virtual void probe(size_t);

	MetadataCons() : Cons() {};
	virtual ~MetadataCons(){};

};

class Sym : public Generic{
private:
	Sym(void){}; //disallowed!
protected:
	Sym(Sym const& s) : Generic(), a(s.a){};
public:
	/*standard stuff*/
	virtual size_t hash(void) const{
		return (size_t) &(*a);
	}
	virtual Sym* clone(Semispace& sp) const{
		return new(sp) Sym(*this);
	}
	virtual size_t get_size(void) const{
		return sizeof(Sym);
	};

	virtual bool is(Generic* gp) const{
		if(gp == this) return 1;
		Sym* sp = dynamic_cast<Sym*>(gp);
		if(sp != NULL){
			return sp->a == a;
		} else return 0;
	};

	virtual bool isnil(void) const {
		return a == NILATOM;
	}

	virtual void probe(size_t);

	Sym(boost::shared_ptr<Atom> const& na) : Generic(), a(na){};
	virtual ~Sym(){};

	/*new stuff*/
	Atom& atom(void){return *a;};
	boost::shared_ptr<Atom> a;
};

class Executor;

class Closure : public Generic {
private:
	boost::shared_ptr<Executor> cd;
	/*possibly add a parallel vector of variable name atoms for
	debugging?
	*/
	std::vector<Generic*> vars;
protected:
	Closure(Closure const& o) : Generic(), cd(o.cd), vars(o.vars) {}
public:
	/*standard stuff*/
	virtual size_t hash(void) const{
		return (size_t) &*cd;
	}
	virtual Closure* clone(Semispace& sp) const{
		return new(sp) Closure(*this);
	}
	virtual size_t get_size(void) const{
		return sizeof(Closure);
	}

	virtual void get_refs(std::stack<Generic**>& s){
		for(size_t i = 0; i < vars.size(); ++i){
			s.push(&vars[i]);
		}
	}

	virtual void probe(size_t);

	Closure(Executor* c, size_t s) :
		Generic(), cd(c), vars(s) {};

	/*new stuff*/
	Executor const& code(void) {return *cd;};
	/*WARNING
	arc2c references closure values starting at index 1 (index 0
	is the function's code itself, and is never used in practice).
	We will have to translate the numbers properly for those cases
	*/
	Generic* & operator[](int i) {return vars[i];}
	Generic* const & operator[](int i) const {return vars[i];}
};

class Integer : public Generic {
private:
	int val;
protected:
	Integer(Integer const& o) : Generic(), val(o.val){}
public:
	/*standard stuff*/
	virtual size_t hash() const {
		return (size_t) val;
	}
	virtual Integer* clone(Semispace& sp) const{
		return new(sp) Integer(*this);
	}
	virtual size_t get_size(void) const{
		return sizeof(Integer);
	}

	virtual void probe(size_t);

	/*new stuff*/
	int integer(void){return val;}
	Integer(int x) : Generic(), val(x) {}
};

/*Used during compilation to hold a bytecode sequence while
converting from a symbolcode list to an internal bytecode
format.
*/
class ArcBytecodeSequence : public Generic {
protected:
	ArcBytecodeSequence(ArcBytecodeSequence const & o)
		: Generic(), seq(o.seq) {}
public:
	/*standard stuff*/
	virtual size_t hash() const{
		return (size_t)(void*) &*seq;
	}
	virtual ArcBytecodeSequence* clone(Semispace& sp) const{
		return new(sp) ArcBytecodeSequence(*this);
	}
	virtual size_t get_size(void) const{
		return sizeof(ArcBytecodeSequence);
	}

	virtual void probe(size_t);

	/*new stuff*/
	void append(Bytecode* b){
		seq->append(b);
	}
	boost::shared_ptr<BytecodeSequence> seq;
	ArcBytecodeSequence(void) : Generic(), seq(new BytecodeSequence()) {}
};

#endif //TYPES_H

<|endoftext|>


<commit_before>#ifndef TYPES_H
#define TYPES_H
#include<stack>
#include<set>
#include<vector>
#include"heaps.hpp"
#include"hashes.hpp"
#include"variables.hpp"

class Semispace;
void* operator new(size_t, Semispace&);
void operator delete(void*, Semispace&);

class ToPointerLock;

class Generic {
private:
	Generic* to_pointer;
protected:
	Generic(void) : to_pointer(NULL) {};
	Generic(Generic const&) : to_pointer(NULL) {};
public:
	friend class Semispace;
	friend class ToPointerLock;

	/*hash should return pretty much just any
	size_t, provided that an unmutated copy of
	that object will have the same hash().
	There is NO NEED TO PROPERLY DISTRIBUTE BITS,
	and it would probably be better not to: the
	table lookup function will use several int-
	to-int hashing functions for the bloom
	filter.
	*/
	virtual size_t hash(void) const =0;
	virtual Generic* clone(Semispace&) const =0;
	/* clone should always have the following code:
	virtual Type* clone(Semispace& sp) const{
		return new(sp) Type(*this);
	}
	*/

	/*gets addresses of references to other objects*/
	virtual void get_refs(std::stack<Generic**>&){};

	/*comparisons*/
	virtual bool is(Generic const* gp) const{return gp == this;}
	virtual bool iso(Generic const* gp) const{return is(gp);}

	virtual size_t get_size(void) const =0;
	/*get_size should always have the following code:
	virtual size_t get_size(void) const {
		return sizeof(Type);
	}
	*/

	/*symbols should change this to check that it's nil*/
	virtual bool isnil(void) const {return 0;};
	bool istrue(void) const {return !isnil();};

	virtual void probe(size_t indent) =0;//for debugging

	virtual ~Generic(){};

	size_t total_size(void);
};

inline bool is(Generic const* a, Generic const* b){ return a->is(b);}
inline bool iso(Generic const* a, Generic const* b){ return a->iso(b);}

/*RAII class to handle the to-pointers
This is used to protect the to-pointers in case of
an exception.  The invariant is, to-pointers are
NULL during normal operation.  If to-pointers must
be used, access to them should be via
ToPointerLock's, so that the to-pointers are reset
to NULL once the non-normal operation (GC,
tracing) are complete.  When the operation
determines that the to-pointers can be left used
(i.e. after a GC run) then it can call the clear()
member function so that it won't bother resetting
the to-pointers.
*/
class ToPointerLock{
private:
	std::set<Generic*> enset;
public:
	void pointto(Generic* from, Generic* to){
		enset.insert(from);
		from->to_pointer = to;
	}
	Generic* to(Generic* from){
		return from->to_pointer;
	}
	/*used to ignore the to-pointers in a successful
	copy-and-sweep GC cycle
	*/
	void good(void){
		enset.clear();
	}
	~ToPointerLock(){
		std::set<Generic*>::iterator i;
		for(i = enset.begin(); i != enset.end(); ++i){
			(*i)->to_pointer = NULL;
		}
	}
};

class Cons : public Generic{
protected:
	Cons(Cons const& s) : Generic(), a(s.a), d(s.d){};
public:
	Generic* a;
	Generic* d;
	/*standard stuff*/
	virtual size_t hash(void) const {
		return a->hash() ^ d->hash();
	}
	virtual Cons* clone(Semispace& sp) const{
		return new(sp) Cons(*this);
	}
	virtual size_t get_size(void) const {
		return sizeof(Cons);
	}

	/*comparisons*/
	virtual bool iso(Generic*gp) const{
		if(is(gp)) {
			return 1;
		} else {
			Cons* cp = dynamic_cast<Cons*>(gp);
			if(cp != NULL){
				return a->iso(cp->a) && d->iso(cp->d);
			} else return 0;
		}
	}

	/*references*/
	virtual void get_refs(std::stack<Generic**>&s){
		s.push(&a);
		s.push(&d);
	}

	virtual void probe(size_t);

	Cons(void) : Generic() {};
	virtual ~Cons(){};

};

class MetadataCons : public Cons {
protected:
	MetadataCons(MetadataCons const& s):Cons(s), line(s.line), file(s.file){};
public:
	Generic* line;
	Generic* file;
	virtual MetadataCons* clone(Semispace& sp) const{
		return new(sp) MetadataCons(*this);
	}
	virtual size_t get_size(void) const {
		return sizeof(MetadataCons);
	}
	virtual void get_refs(std::stack<Generic**>& s){
		Cons::get_refs(s);
		s.push(&line);
		s.push(&file);
	}

	virtual void probe(size_t);

	MetadataCons() : Cons() {};
	virtual ~MetadataCons(){};

};

class Sym : public Generic{
private:
	boost::shared_ptr<Atom> a;
	Sym(void){}; //disallowed!
protected:
	Sym(Sym const& s) : Generic(), a(s.a){};
public:
	/*standard stuff*/
	virtual size_t hash(void) const{
		return (size_t) &(*a);
	}
	virtual Sym* clone(Semispace& sp) const{
		return new(sp) Sym(*this);
	}
	virtual size_t get_size(void) const{
		return sizeof(Sym);
	};

	virtual bool is(Generic* gp) const{
		if(gp == this) return 1;
		Sym* sp = dynamic_cast<Sym*>(gp);
		if(sp != NULL){
			return sp->a == a;
		} else return 0;
	};

	virtual bool isnil(void) const {
		return a == NILATOM;
	}

	virtual void probe(size_t);

	Sym(boost::shared_ptr<Atom> const& na) : Generic(), a(na){};
	virtual ~Sym(){};

	/*new stuff*/
	Atom& atom(void){return *a;};
};

class Executor;

class Closure : public Generic {
private:
	boost::shared_ptr<Executor> cd;
	/*possibly add a parallel vector of variable name atoms for
	debugging?
	*/
	std::vector<Generic*> vars;
protected:
	Closure(Closure const& o) : Generic(), cd(o.cd), vars(o.vars) {}
public:
	Executor const& code(void) {return *cd;};
	/*standard stuff*/
	virtual size_t hash(void) const{
		return (size_t) &*cd;
	}
	virtual Closure* clone(Semispace& sp) const{
		return new(sp) Closure(*this);
	}
	virtual size_t get_size(void) const{
		return sizeof(Closure);
	}

	Closure(boost::shared_ptr<Executor> c, size_t s) :
		Generic(), cd(c), vars(s) {}
};

#endif //TYPES_H

<commit_msg>Added declaration of Closure::probe, added operator[] for closures<commit_after>#ifndef TYPES_H
#define TYPES_H
#include<stack>
#include<set>
#include<vector>
#include"heaps.hpp"
#include"hashes.hpp"
#include"variables.hpp"

class Semispace;
void* operator new(size_t, Semispace&);
void operator delete(void*, Semispace&);

class ToPointerLock;

class Generic {
private:
	Generic* to_pointer;
protected:
	Generic(void) : to_pointer(NULL) {};
	Generic(Generic const&) : to_pointer(NULL) {};
public:
	friend class Semispace;
	friend class ToPointerLock;

	/*hash should return pretty much just any
	size_t, provided that an unmutated copy of
	that object will have the same hash().
	There is NO NEED TO PROPERLY DISTRIBUTE BITS,
	and it would probably be better not to: the
	table lookup function will use several int-
	to-int hashing functions for the bloom
	filter.
	*/
	virtual size_t hash(void) const =0;
	virtual Generic* clone(Semispace&) const =0;
	/* clone should always have the following code:
	virtual Type* clone(Semispace& sp) const{
		return new(sp) Type(*this);
	}
	*/

	/*gets addresses of references to other objects*/
	virtual void get_refs(std::stack<Generic**>&){};

	/*comparisons*/
	virtual bool is(Generic const* gp) const{return gp == this;}
	virtual bool iso(Generic const* gp) const{return is(gp);}

	virtual size_t get_size(void) const =0;
	/*get_size should always have the following code:
	virtual size_t get_size(void) const {
		return sizeof(Type);
	}
	*/

	/*symbols should change this to check that it's nil*/
	virtual bool isnil(void) const {return 0;};
	bool istrue(void) const {return !isnil();};

	virtual void probe(size_t indent) =0;//for debugging

	virtual ~Generic(){};

	size_t total_size(void);
};

inline bool is(Generic const* a, Generic const* b){ return a->is(b);}
inline bool iso(Generic const* a, Generic const* b){ return a->iso(b);}

/*RAII class to handle the to-pointers
This is used to protect the to-pointers in case of
an exception.  The invariant is, to-pointers are
NULL during normal operation.  If to-pointers must
be used, access to them should be via
ToPointerLock's, so that the to-pointers are reset
to NULL once the non-normal operation (GC,
tracing) are complete.  When the operation
determines that the to-pointers can be left used
(i.e. after a GC run) then it can call the clear()
member function so that it won't bother resetting
the to-pointers.
*/
class ToPointerLock{
private:
	std::set<Generic*> enset;
public:
	void pointto(Generic* from, Generic* to){
		enset.insert(from);
		from->to_pointer = to;
	}
	Generic* to(Generic* from){
		return from->to_pointer;
	}
	/*used to ignore the to-pointers in a successful
	copy-and-sweep GC cycle
	*/
	void good(void){
		enset.clear();
	}
	~ToPointerLock(){
		std::set<Generic*>::iterator i;
		for(i = enset.begin(); i != enset.end(); ++i){
			(*i)->to_pointer = NULL;
		}
	}
};

class Cons : public Generic{
protected:
	Cons(Cons const& s) : Generic(), a(s.a), d(s.d){};
public:
	Generic* a;
	Generic* d;
	/*standard stuff*/
	virtual size_t hash(void) const {
		return a->hash() ^ d->hash();
	}
	virtual Cons* clone(Semispace& sp) const{
		return new(sp) Cons(*this);
	}
	virtual size_t get_size(void) const {
		return sizeof(Cons);
	}

	/*comparisons*/
	virtual bool iso(Generic*gp) const{
		if(is(gp)) {
			return 1;
		} else {
			Cons* cp = dynamic_cast<Cons*>(gp);
			if(cp != NULL){
				return a->iso(cp->a) && d->iso(cp->d);
			} else return 0;
		}
	}

	/*references*/
	virtual void get_refs(std::stack<Generic**>&s){
		s.push(&a);
		s.push(&d);
	}

	virtual void probe(size_t);

	Cons(void) : Generic() {};
	virtual ~Cons(){};

};

class MetadataCons : public Cons {
protected:
	MetadataCons(MetadataCons const& s):Cons(s), line(s.line), file(s.file){};
public:
	Generic* line;
	Generic* file;
	virtual MetadataCons* clone(Semispace& sp) const{
		return new(sp) MetadataCons(*this);
	}
	virtual size_t get_size(void) const {
		return sizeof(MetadataCons);
	}
	virtual void get_refs(std::stack<Generic**>& s){
		Cons::get_refs(s);
		s.push(&line);
		s.push(&file);
	}

	virtual void probe(size_t);

	MetadataCons() : Cons() {};
	virtual ~MetadataCons(){};

};

class Sym : public Generic{
private:
	boost::shared_ptr<Atom> a;
	Sym(void){}; //disallowed!
protected:
	Sym(Sym const& s) : Generic(), a(s.a){};
public:
	/*standard stuff*/
	virtual size_t hash(void) const{
		return (size_t) &(*a);
	}
	virtual Sym* clone(Semispace& sp) const{
		return new(sp) Sym(*this);
	}
	virtual size_t get_size(void) const{
		return sizeof(Sym);
	};

	virtual bool is(Generic* gp) const{
		if(gp == this) return 1;
		Sym* sp = dynamic_cast<Sym*>(gp);
		if(sp != NULL){
			return sp->a == a;
		} else return 0;
	};

	virtual bool isnil(void) const {
		return a == NILATOM;
	}

	virtual void probe(size_t);

	Sym(boost::shared_ptr<Atom> const& na) : Generic(), a(na){};
	virtual ~Sym(){};

	/*new stuff*/
	Atom& atom(void){return *a;};
};

class Executor;

class Closure : public Generic {
private:
	boost::shared_ptr<Executor> cd;
	/*possibly add a parallel vector of variable name atoms for
	debugging?
	*/
	std::vector<Generic*> vars;
protected:
	Closure(Closure const& o) : Generic(), cd(o.cd), vars(o.vars) {}
public:
	/*standard stuff*/
	virtual size_t hash(void) const{
		return (size_t) &*cd;
	}
	virtual Closure* clone(Semispace& sp) const{
		return new(sp) Closure(*this);
	}
	virtual size_t get_size(void) const{
		return sizeof(Closure);
	}

	virtual void probe(size_t);

	Closure(boost::shared_ptr<Executor> c, size_t s) :
		Generic(), cd(c), vars(s) {};

	/*new stuff*/
	Executor const& code(void) {return *cd;};
	Generic* & operator[](int i) {return vars[i];}
	Generic* const & operator[](int i) const {return vars[i];}
};

#endif //TYPES_H

<|endoftext|>


<commit_before>/**
 * @file
 */
#pragma once

#include <memory>

namespace bi {
/**
 * Cast away the const-ness of a pointer. Usually used for the @c this
 * pointer to implement the read-write semantics of objects.
 */
template<class From, class To = From>
To* cast(const From* o) {
  return const_cast<To*>(o);
}

/**
 * Cast away the const-ness of a reference. Usually used for passing rvalues
 * to assignment operator overloads requiring lvalue reference argument.
 */
template<class From, class To = From>
To& cast(const From& o) {
  return const_cast<To&>(o);
}

/**
 * Simultaneously cast a shared pointer to a derived type and remove its
 * constness.
 */
template<class From, class To = From>
std::shared_ptr<To> cast(const std::shared_ptr<const From>& o) {
  return std::dynamic_pointer_cast<To>(std::const_pointer_cast<From>(o));
}
}
<commit_msg>Corrected cast for pointer types.<commit_after>/**
 * @file
 */
#pragma once

#include <memory>

namespace bi {
/**
 * Cast away the const-ness of a pointer. Usually used for the @c this
 * pointer to implement the read-write semantics of objects.
 */
template<class T>
T* cast(const T* o) {
  return const_cast<T*>(o);
}

/**
 * Cast away the const-ness of a reference. Usually used for passing rvalues
 * to assignment operator overloads requiring lvalue reference argument.
 */
template<class T>
T& cast(const T& o) {
  return const_cast<T&>(o);
}

/**
 * Simultaneously cast a shared pointer to a derived type and remove its
 * constness.
 */
template<class To, class From>
std::shared_ptr<To> cast(const std::shared_ptr<const From>& o) {
  return std::dynamic_pointer_cast<To>(std::const_pointer_cast<From>(o));
}
}
<|endoftext|>


<commit_before>#include <iostream>

#include <boost/program_options.hpp>

#include "connection.hpp"
#include "transaction_single_op.hpp"

using namespace std;
using namespace scalaris;
namespace po = boost::program_options;

namespace std {
  istream& operator>>(istream& in, std::pair<std::string,std::string>& ss) {
  string s;
  in >> s;
  const size_t sep = s.find(',');
  if (sep==string::npos) {
    ss.first = s;
    ss.second = string();
  } else {
    ss.first  = s.substr(0,sep);
    ss.second = s.substr(sep+1);
  }
  return in;
}}

template<typename F>
void exec_call(F& f){
  try {
    Connection c { "localhost" };
    TransactionSingleOp op = { c };
    f(op);
  } catch (std::runtime_error& e) {
    cout << "std::runtime_error: " << e.what() << endl;
    exit(EXIT_FAILURE);
  } catch (ConnectionError& e) {
    cout << "ConnectionError: " << e.what() << endl;
    exit(EXIT_FAILURE);
  } catch (MalFormedJsonError& e) {
    cout << "MalFormedJsonError: " << e.what() << endl;
    exit(EXIT_FAILURE);
  } catch (ReadFailedError& e) {
    cout << "ReadFailedError: " << e.what() << endl;
    exit(EXIT_FAILURE);
  } catch (NotFoundError& e) {
    cout << "NotFoundError: " << e.what() << endl;
    exit(EXIT_FAILURE);
  } catch (WriteFailedError& e) {
    cout << "WriteFailedError: " << e.what() << endl;
    exit(EXIT_FAILURE);
  } catch (CommitFailedError& e) {
    cout << "CommitFailedError: " << e.what() << endl;
    exit(EXIT_FAILURE);
  } catch (NotSupportedError& e) {
    cout << "NotSupportedError: " << e.what() << endl;
    exit(EXIT_FAILURE);
  }
}

int main(int argc, char **argv) {
  // Declare the supported options.
  po::options_description desc("Allowed options");
  desc.add_options()
    ("help", "produce help message")
    ("read", po::value<std::string>(), "read key")
    ("write", po::value<pair<string, string>>(), "write key,value")
    ;

  po::variables_map vm;
  po::store(po::parse_command_line(argc, argv, desc), vm);
  po::notify(vm);

  try {
    if (vm.count("help")) {
      cout << desc << "\n";
      return 0;
    } else if (vm.count("read")) {
      string key = vm["read"].as<string>();
      auto p = [key](TransactionSingleOp& op) {
        std::string value = op.read(key);
        cout << value << endl;
      };
      exec_call(p);
    } else if (vm.count("write")) {
      try {
        pair<string,string> kv = vm["write"].as<pair<string,string>>();
        string key = get<0>(kv);
        string value = get<1>(kv);
        auto p = [key,value](TransactionSingleOp& op) {
          op.write(key,value);
        };
        exec_call(p);
      } catch(const boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_any_cast> >& e) {
        cout << "could not convert write parameter to a pair of strings" << endl;
        exit(EXIT_FAILURE);
      }
    } else {
      cout << desc << "\n";
      return 0;
    }
  } catch (const Json::LogicError& e) {
    cout << "Json error: " << e.what() << endl;
    exit(EXIT_FAILURE);
  }

  return 0;
}
<commit_msg>cpp: check for exceptions when reading command line parameters<commit_after>#include <iostream>

#include <boost/program_options.hpp>

#include "connection.hpp"
#include "transaction_single_op.hpp"

using namespace std;
using namespace scalaris;
namespace po = boost::program_options;

namespace std {
  istream& operator>>(istream& in, std::pair<std::string,std::string>& ss) {
  string s;
  in >> s;
  const size_t sep = s.find(',');
  if (sep==string::npos) {
    ss.first = s;
    ss.second = string();
  } else {
    ss.first  = s.substr(0,sep);
    ss.second = s.substr(sep+1);
  }
  return in;
}}

template<typename F>
void exec_call(F& f){
  try {
    Connection c { "localhost" };
    TransactionSingleOp op = { c };
    f(op);
  } catch (std::runtime_error& e) {
    cout << "std::runtime_error: " << e.what() << endl;
    exit(EXIT_FAILURE);
  } catch (ConnectionError& e) {
    cout << "ConnectionError: " << e.what() << endl;
    exit(EXIT_FAILURE);
  } catch (MalFormedJsonError& e) {
    cout << "MalFormedJsonError: " << e.what() << endl;
    exit(EXIT_FAILURE);
  } catch (ReadFailedError& e) {
    cout << "ReadFailedError: " << e.what() << endl;
    exit(EXIT_FAILURE);
  } catch (NotFoundError& e) {
    cout << "NotFoundError: " << e.what() << endl;
    exit(EXIT_FAILURE);
  } catch (WriteFailedError& e) {
    cout << "WriteFailedError: " << e.what() << endl;
    exit(EXIT_FAILURE);
  } catch (CommitFailedError& e) {
    cout << "CommitFailedError: " << e.what() << endl;
    exit(EXIT_FAILURE);
  } catch (NotSupportedError& e) {
    cout << "NotSupportedError: " << e.what() << endl;
    exit(EXIT_FAILURE);
  }
}

int main(int argc, char **argv) {
  // Declare the supported options.
  po::options_description desc("Allowed options");
  desc.add_options()
    ("help", "produce help message")
    ("read", po::value<std::string>(), "read key")
    ("write", po::value<pair<string, string>>(), "write key,value")
    ;

  po::variables_map vm;
  po::store(po::parse_command_line(argc, argv, desc), vm);
  po::notify(vm);

  try {
    if (vm.count("help")) {
      cout << desc << "\n";
      return 0;
    } else if (vm.count("read")) {
      try {
        string key = vm["read"].as<string>();
        auto p = [key](TransactionSingleOp& op) {
          std::string value = op.read(key);
          cout << value << endl;
        };
        exec_call(p);
      } catch(const boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_any_cast> >& e) {
        cout << "could not convert read parameter to a string" << endl;
        exit(EXIT_FAILURE);
      }
    } else if (vm.count("write")) {
      try {
        pair<string,string> kv = vm["write"].as<pair<string,string>>();
        string key = get<0>(kv);
        string value = get<1>(kv);
        auto p = [key,value](TransactionSingleOp& op) {
          op.write(key,value);
        };
        exec_call(p);
      } catch(const boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_any_cast> >& e) {
        cout << "could not convert write parameter to a pair of strings" << endl;
        exit(EXIT_FAILURE);
      }
    } else {
      cout << desc << "\n";
      return 0;
    }
  } catch (const Json::LogicError& e) {
    cout << "Json error: " << e.what() << endl;
    exit(EXIT_FAILURE);
  }

  return 0;
}
<|endoftext|>