<commit_before>#include "string_util.h"

namespace kagami {
  bool IsStringFamily(Object &obj) {
    return compare(obj.GetTypeId(), { kTypeIdString,kTypeIdWideString });
  }

  Message CreateStringFromArray(ObjectMap &p) {
    EXPECT_TYPE(p, "src", kTypeIdArray);
    auto &base = p.Cast<ObjectArray>("src");
    shared_ptr<string> dest(make_shared<string>());

    for (auto it = base.begin(); it != base.end(); ++it) {
      if (it->GetTypeId() == kTypeIdInt) {
        dest->append(1, static_cast<char>(it->Cast<long>()));
        continue;
      }

      if (it->GetTypeId() != kTypeIdString) {
        continue;
      }

      dest->append(it->Cast<string>());
    }

    return Message().SetObject(Object(dest, kTypeIdString));
  }

  //String
  Message StringConstructor(ObjectMap &p) {
    Object &obj = p["raw_string"];
    Object base;

    EXPECT(IsStringFamily(obj),
      "String constructor can't accept this object.");

    if (obj.GetTypeId() == kTypeIdWideString) {
      wstring wstr = obj.Cast<wstring>();
      string output = ws2s(wstr);

      base.ManageContent(make_shared<string>(output), kTypeIdString)
        .SetConstructorFlag();
    }
    else if (obj.GetTypeId() == kTypeIdString) {
      string copy = obj.Cast<string>();
      base.ManageContent(make_shared<string>(copy), kTypeIdString)
        .SetConstructorFlag();
    }
    else {
      string output = obj.Cast<string>();

      base.ManageContent(make_shared<string>(output), kTypeIdString)
        .SetConstructorFlag();
    }

    return Message().SetObject(base);
  }

  Message StringCompare(ObjectMap &p) {
    auto &rhs = p[kStrRightHandSide];
    string lhs = p[kStrObject].Cast<string>();

    string type_id = rhs.GetTypeId();
    bool result = false;

    if (type_id == kTypeIdString) {
      string rhs_str = rhs.Cast<string>();
      result = (lhs == rhs_str);
    }

    return Message().SetObject(result);
  }

  Message StringToArray(ObjectMap &p) {
    auto &str = p.Cast<string>(kStrObject);
    shared_ptr<ObjectArray> base(make_shared<ObjectArray>());

    base->reserve(str.size());

    for (auto &unit : str) {
      base->emplace_back(string().append(1, unit));
    }

    return Message().SetObject(Object(base, kTypeIdArray));
  }

  //InStream-new
  Message NewInStream(ObjectMap &p) {
    EXPECT_TYPE(p, "path", kTypeIdString);
    wstring path = s2ws(p.Cast<string>("path"));

    shared_ptr<wifstream> ifs(
      make_shared<wifstream>(path, std::ios::in)
    );

    return Message().SetObject(Object(ifs, kTypeIdInStream));
  }

  Message InStreamGet(ObjectMap &p) {
    wifstream &ifs = p.Cast<wifstream>(kStrObject);

    if (!ifs.good()) {
      return Message(kCodeBadStream, "Invalid instream.", kStateError);
    }

    if (ifs.eof()) {
      return Message("");
    }

    wstring wstr;
    std::getline(ifs, wstr);
    string str = ws2s(wstr);
    if (str.back() == '\n' || str.back() == '\0') str.pop_back();

    return Message().SetObject(str);
  }

  Message InStreamEOF(ObjectMap &p) {
    wifstream &ifs = p.Cast<wifstream>(kStrObject);
    return Message().SetObject(ifs.eof());
  }

  //OutStream
  Message OutStreamConstructor(ObjectMap &p) {
    EXPECT_TYPE(p, "path", kTypeIdString);
    EXPECT_TYPE(p, "mode", kTypeIdString);

    string path = p.Cast<string>("path");
    string mode = p.Cast<string>("mode");

    shared_ptr<ofstream> ofs;
    bool append = (mode == "append");
    bool truncate = (mode == "truncate");

    if (!append && truncate) {
      ofs = make_shared<ofstream>(ofstream(path.c_str(),
        std::ios::out | std::ios::trunc));
    }
    else if (append && !truncate) {
      ofs = make_shared<ofstream>(ofstream(path.c_str(),
        std::ios::out | std::ios::app));
    }

    return Message().SetObject(Object(ofs, kTypeIdOutStream));
  }

  Message OutStreamWrite(ObjectMap &p) {
    ofstream &ofs = p.Cast<ofstream>(kStrObject);
    bool result = true;

    if (!ofs.good()) {
      result = false;
    }
    else {
      if (p.CheckTypeId("str", kTypeIdString)) {
        string origin = p.Cast<string>("str");
        ofs << origin;
      }
      else {
        result = false;
      }
    }

    return Message().SetObject(result);
  }

  //regex
  Message RegexConstructor(ObjectMap &p) {
    EXPECT_TYPE(p, "pattern", kTypeIdString);

    string pattern_string = p.Cast<string>("pattern");
    shared_ptr<regex> reg = make_shared<regex>(regex(pattern_string));

    return Message().SetObject(Object(reg, kTypeIdRegex));
  }

  Message RegexMatch(ObjectMap &p) {
    EXPECT_TYPE(p, "str", kTypeIdString);

    string str = p.Cast<string>("str");
    auto &pat = p.Cast<regex>(kStrObject);
    bool result = regex_match(str, pat);

    return Message().SetObject(result);
  }

  //wstring
  Message WideStringContructor(ObjectMap &p) {
    EXPECT_TYPE(p, "raw_string", kTypeIdString);
    Object obj = p["raw_string"];

    string output = obj.Cast<string>();
    wstring wstr = s2ws(output);

    return Message()
      .SetObject(Object(make_shared<wstring>(wstr), kTypeIdWideString));
  }

  Message WideStringCompare(ObjectMap &p) {
    auto &rhs = p[kStrRightHandSide];
    wstring lhs = p[kStrObject].Cast<wstring>();
    bool result = false;
    if (rhs.GetTypeId() == kTypeIdWideString) {
      wstring rhs_wstr = rhs.Cast<wstring>();

      result = (lhs == rhs_wstr);
    }

    return Message().SetObject(result);
  }

  //Function
  Message FunctionGetId(ObjectMap &p) {
    auto &interface = p.Cast<Interface>(kStrObject);
    return Message(interface.GetId());
  }

  Message FunctionGetParameters(ObjectMap &p) {
    auto &interface = p.Cast<Interface>(kStrObject);
    shared_ptr<ObjectArray> dest_base = make_shared<ObjectArray>();
    auto origin_vector = interface.GetParameters();

    for (auto it = origin_vector.begin(); it != origin_vector.end(); ++it) {
      dest_base->emplace_back(Object(make_shared<string>(*it), kTypeIdString));
    }

    return Message().SetObject(Object(dest_base, kTypeIdArray));
  }

  Message FunctionCompare(ObjectMap &p) {
    auto &rhs = p[kStrRightHandSide];
    auto &lhs = p[kStrObject].Cast<Interface>();

    string type_id = rhs.GetTypeId();
    bool result = false;

    if (type_id == kTypeIdFunction) {
      auto &rhs_interface = rhs.Cast<Interface>();

      result = (lhs == rhs_interface);
    }

    return Message().SetObject(result);
  }

  void InitBaseTypes() {
    using management::type::NewTypeSetup;
    using management::CreateNewInterface;

    NewTypeSetup(kTypeIdFunction, SimpleSharedPtrCopy<Interface>)
      .InitMethods(
        {
          Interface(FunctionGetId, "", "id"),
          Interface(FunctionGetParameters, "", "params"),
          Interface(FunctionCompare, kStrRightHandSide, kStrCompare)
        }
    );

    NewTypeSetup(kTypeIdString, SimpleSharedPtrCopy<string>)
      .InitConstructor(
        Interface(StringConstructor, "raw_string", "string")
      )
      .InitMethods(
        {
          Interface(StringFamilyGetElement<string>, "index", "__at"),
          Interface(StringFamilyPrint<string, std::ostream>, "", "__print"),
          Interface(StringFamilySubStr<string>, "start|size", "substr"),
          Interface(GetStringFamilySize<string>, "", "size"),
          Interface(StringFamilyConverting<wstring, string>, "", "to_wide"),
          Interface(StringCompare, kStrRightHandSide, kStrCompare),
          Interface(StringToArray, "","to_array")
        }
    );

    NewTypeSetup(kTypeIdInStream, FakeCopy<wifstream>)
      .InitConstructor(
        Interface(NewInStream, "path", "instream")
      )
      .InitMethods(
        {
          Interface(InStreamGet, "", "get"),
          Interface(InStreamEOF, "", "eof"),
          Interface(StreamFamilyClose<wifstream>, "", "close")
        }
    );

    NewTypeSetup(kTypeIdOutStream, FakeCopy<ofstream>)
      .InitConstructor(
        Interface(OutStreamConstructor, "path|mode", "outstream")
      )
      .InitMethods(
        {
          Interface(OutStreamWrite, "str", "write"),
          Interface(StreamFamilyState<ofstream>, "", "good"),
          Interface(StreamFamilyClose<ofstream>, "", "close")
        }
    );
    management::CreateConstantObject("kOutstreamModeAppend", Object("'append'"));
    management::CreateConstantObject("kOutstreamModeTruncate", Object("'truncate'"));

    NewTypeSetup(kTypeIdRegex, FakeCopy<regex>)
      .InitConstructor(
        Interface(RegexConstructor, "pattern", "regex")
      )
      .InitMethods(
        {
          Interface(RegexMatch, "str", "match")
        }
    );

    NewTypeSetup(kTypeIdWideString, SimpleSharedPtrCopy<wstring>)
      .InitConstructor(
        Interface(WideStringContructor, "raw_string", "wstring")
      )
      .InitMethods(
        {
          Interface(GetStringFamilySize<wstring>,  "", "size"),
          Interface(StringFamilyGetElement<wstring>, "index", "__at"),
          Interface(StringFamilyPrint<wstring, std::wostream>, "", "__print"),
          Interface(StringFamilySubStr<wstring>, "start|size", "substr"),
          Interface(StringFamilyConverting<string, wstring>, "", "to_byte"),
          Interface(WideStringCompare, kStrRightHandSide, kStrCompare)
        }
    );

    CreateNewInterface(Interface(DecimalConvert<2>, "str", "bin"));
    CreateNewInterface(Interface(DecimalConvert<8>, "str", "octa"));
    CreateNewInterface(Interface(DecimalConvert<16>, "str", "hex"));
    CreateNewInterface(Interface(CreateStringFromArray, "src", "ar2string"));

    EXPORT_CONSTANT(kTypeIdFunction);
    EXPORT_CONSTANT(kTypeIdString);
    EXPORT_CONSTANT(kTypeIdInStream);
    EXPORT_CONSTANT(kTypeIdOutStream);
    EXPORT_CONSTANT(kTypeIdRegex);
    EXPORT_CONSTANT(kTypeIdWideString);
  }
}<commit_msg>Update<commit_after>#include "string_util.h"

namespace kagami {
  bool IsStringFamily(Object &obj) {
    return compare(obj.GetTypeId(), { kTypeIdString,kTypeIdWideString });
  }

  Message CreateStringFromArray(ObjectMap &p) {
    EXPECT_TYPE(p, "src", kTypeIdArray);
    auto &base = p.Cast<ObjectArray>("src");
    shared_ptr<string> dest(make_shared<string>());

    for (auto it = base.begin(); it != base.end(); ++it) {
      if (it->GetTypeId() == kTypeIdInt) {
        dest->append(1, static_cast<char>(it->Cast<long>()));
        continue;
      }

      if (it->GetTypeId() != kTypeIdString) {
        continue;
      }

      dest->append(it->Cast<string>());
    }

    return Message().SetObject(Object(dest, kTypeIdString));
  }

  //String
  Message StringConstructor(ObjectMap &p) {
    Object &obj = p["raw_string"];
    Object base;

    EXPECT(IsStringFamily(obj),
      "String constructor can't accept this object.");

    if (obj.GetTypeId() == kTypeIdWideString) {
      wstring wstr = obj.Cast<wstring>();
      string output = ws2s(wstr);

      base.ManageContent(make_shared<string>(output), kTypeIdString)
        .SetConstructorFlag();
    }
    else if (obj.GetTypeId() == kTypeIdString) {
      string copy = obj.Cast<string>();
      base.ManageContent(make_shared<string>(copy), kTypeIdString)
        .SetConstructorFlag();
    }
    else {
      string output = obj.Cast<string>();

      base.ManageContent(make_shared<string>(output), kTypeIdString)
        .SetConstructorFlag();
    }

    return Message().SetObject(base);
  }

  Message StringCompare(ObjectMap &p) {
    auto &rhs = p[kStrRightHandSide];
    string lhs = p[kStrObject].Cast<string>();

    string type_id = rhs.GetTypeId();
    bool result = false;

    if (type_id == kTypeIdString) {
      string rhs_str = rhs.Cast<string>();
      result = (lhs == rhs_str);
    }

    return Message().SetObject(result);
  }

  Message StringToArray(ObjectMap &p) {
    auto &str = p.Cast<string>(kStrObject);
    shared_ptr<ObjectArray> base(make_shared<ObjectArray>());

    base->reserve(str.size());

    for (auto &unit : str) {
      base->emplace_back(string().append(1, unit));
    }

    return Message().SetObject(Object(base, kTypeIdArray));
  }

  //InStream-new
  Message NewInStream(ObjectMap &p) {
    EXPECT_TYPE(p, "path", kTypeIdString);
    wstring path = s2ws(p.Cast<string>("path"));

    shared_ptr<wifstream> ifs(make_shared<wifstream>());

    ifs->open(path, std::ios::in);

    return Message().SetObject(Object(ifs, kTypeIdInStream));
  }

  Message InStreamGet(ObjectMap &p) {
    wifstream &ifs = p.Cast<wifstream>(kStrObject);

    if (!ifs.good()) {
      return Message(kCodeBadStream, "Invalid instream.", kStateError);
    }

    if (ifs.eof()) {
      return Message("");
    }

    wstring wstr;
    std::getline(ifs, wstr);
    string str = ws2s(wstr);
    if (str.back() == '\n' || str.back() == '\0') str.pop_back();

    return Message().SetObject(str);
  }

  Message InStreamEOF(ObjectMap &p) {
    wifstream &ifs = p.Cast<wifstream>(kStrObject);
    return Message().SetObject(ifs.eof());
  }

  //OutStream
  Message OutStreamConstructor(ObjectMap &p) {
    EXPECT_TYPE(p, "path", kTypeIdString);
    EXPECT_TYPE(p, "mode", kTypeIdString);

    string path = p.Cast<string>("path");
    string mode = p.Cast<string>("mode");

    shared_ptr<ofstream> ofs;
    bool append = (mode == "append");
    bool truncate = (mode == "truncate");

    if (!append && truncate) {
      ofs = make_shared<ofstream>(ofstream(path.c_str(),
        std::ios::out | std::ios::trunc));
    }
    else if (append && !truncate) {
      ofs = make_shared<ofstream>(ofstream(path.c_str(),
        std::ios::out | std::ios::app));
    }

    return Message().SetObject(Object(ofs, kTypeIdOutStream));
  }

  Message OutStreamWrite(ObjectMap &p) {
    ofstream &ofs = p.Cast<ofstream>(kStrObject);
    bool result = true;

    if (!ofs.good()) {
      result = false;
    }
    else {
      if (p.CheckTypeId("str", kTypeIdString)) {
        string origin = p.Cast<string>("str");
        ofs << origin;
      }
      else {
        result = false;
      }
    }

    return Message().SetObject(result);
  }

  //regex
  Message RegexConstructor(ObjectMap &p) {
    EXPECT_TYPE(p, "pattern", kTypeIdString);

    string pattern_string = p.Cast<string>("pattern");
    shared_ptr<regex> reg = make_shared<regex>(regex(pattern_string));

    return Message().SetObject(Object(reg, kTypeIdRegex));
  }

  Message RegexMatch(ObjectMap &p) {
    EXPECT_TYPE(p, "str", kTypeIdString);

    string str = p.Cast<string>("str");
    auto &pat = p.Cast<regex>(kStrObject);
    bool result = regex_match(str, pat);

    return Message().SetObject(result);
  }

  //wstring
  Message WideStringContructor(ObjectMap &p) {
    EXPECT_TYPE(p, "raw_string", kTypeIdString);
    Object obj = p["raw_string"];

    string output = obj.Cast<string>();
    wstring wstr = s2ws(output);

    return Message()
      .SetObject(Object(make_shared<wstring>(wstr), kTypeIdWideString));
  }

  Message WideStringCompare(ObjectMap &p) {
    auto &rhs = p[kStrRightHandSide];
    wstring lhs = p[kStrObject].Cast<wstring>();
    bool result = false;
    if (rhs.GetTypeId() == kTypeIdWideString) {
      wstring rhs_wstr = rhs.Cast<wstring>();

      result = (lhs == rhs_wstr);
    }

    return Message().SetObject(result);
  }

  //Function
  Message FunctionGetId(ObjectMap &p) {
    auto &interface = p.Cast<Interface>(kStrObject);
    return Message(interface.GetId());
  }

  Message FunctionGetParameters(ObjectMap &p) {
    auto &interface = p.Cast<Interface>(kStrObject);
    shared_ptr<ObjectArray> dest_base = make_shared<ObjectArray>();
    auto origin_vector = interface.GetParameters();

    for (auto it = origin_vector.begin(); it != origin_vector.end(); ++it) {
      dest_base->emplace_back(Object(make_shared<string>(*it), kTypeIdString));
    }

    return Message().SetObject(Object(dest_base, kTypeIdArray));
  }

  Message FunctionCompare(ObjectMap &p) {
    auto &rhs = p[kStrRightHandSide];
    auto &lhs = p[kStrObject].Cast<Interface>();

    string type_id = rhs.GetTypeId();
    bool result = false;

    if (type_id == kTypeIdFunction) {
      auto &rhs_interface = rhs.Cast<Interface>();

      result = (lhs == rhs_interface);
    }

    return Message().SetObject(result);
  }

  void InitBaseTypes() {
    using management::type::NewTypeSetup;
    using management::CreateNewInterface;

    NewTypeSetup(kTypeIdFunction, SimpleSharedPtrCopy<Interface>)
      .InitMethods(
        {
          Interface(FunctionGetId, "", "id"),
          Interface(FunctionGetParameters, "", "params"),
          Interface(FunctionCompare, kStrRightHandSide, kStrCompare)
        }
    );

    NewTypeSetup(kTypeIdString, SimpleSharedPtrCopy<string>)
      .InitConstructor(
        Interface(StringConstructor, "raw_string", "string")
      )
      .InitMethods(
        {
          Interface(StringFamilyGetElement<string>, "index", "__at"),
          Interface(StringFamilyPrint<string, std::ostream>, "", "__print"),
          Interface(StringFamilySubStr<string>, "start|size", "substr"),
          Interface(GetStringFamilySize<string>, "", "size"),
          Interface(StringFamilyConverting<wstring, string>, "", "to_wide"),
          Interface(StringCompare, kStrRightHandSide, kStrCompare),
          Interface(StringToArray, "","to_array")
        }
    );

    NewTypeSetup(kTypeIdInStream, FakeCopy<wifstream>)
      .InitConstructor(
        Interface(NewInStream, "path", "instream")
      )
      .InitMethods(
        {
          Interface(InStreamGet, "", "get"),
          Interface(InStreamEOF, "", "eof"),
          Interface(StreamFamilyClose<wifstream>, "", "close")
        }
    );

    NewTypeSetup(kTypeIdOutStream, FakeCopy<ofstream>)
      .InitConstructor(
        Interface(OutStreamConstructor, "path|mode", "outstream")
      )
      .InitMethods(
        {
          Interface(OutStreamWrite, "str", "write"),
          Interface(StreamFamilyState<ofstream>, "", "good"),
          Interface(StreamFamilyClose<ofstream>, "", "close")
        }
    );
    management::CreateConstantObject("kOutstreamModeAppend", Object("'append'"));
    management::CreateConstantObject("kOutstreamModeTruncate", Object("'truncate'"));

    NewTypeSetup(kTypeIdRegex, FakeCopy<regex>)
      .InitConstructor(
        Interface(RegexConstructor, "pattern", "regex")
      )
      .InitMethods(
        {
          Interface(RegexMatch, "str", "match")
        }
    );

    NewTypeSetup(kTypeIdWideString, SimpleSharedPtrCopy<wstring>)
      .InitConstructor(
        Interface(WideStringContructor, "raw_string", "wstring")
      )
      .InitMethods(
        {
          Interface(GetStringFamilySize<wstring>,  "", "size"),
          Interface(StringFamilyGetElement<wstring>, "index", "__at"),
          Interface(StringFamilyPrint<wstring, std::wostream>, "", "__print"),
          Interface(StringFamilySubStr<wstring>, "start|size", "substr"),
          Interface(StringFamilyConverting<string, wstring>, "", "to_byte"),
          Interface(WideStringCompare, kStrRightHandSide, kStrCompare)
        }
    );

    CreateNewInterface(Interface(DecimalConvert<2>, "str", "bin"));
    CreateNewInterface(Interface(DecimalConvert<8>, "str", "octa"));
    CreateNewInterface(Interface(DecimalConvert<16>, "str", "hex"));
    CreateNewInterface(Interface(CreateStringFromArray, "src", "ar2string"));

    EXPORT_CONSTANT(kTypeIdFunction);
    EXPORT_CONSTANT(kTypeIdString);
    EXPORT_CONSTANT(kTypeIdInStream);
    EXPORT_CONSTANT(kTypeIdOutStream);
    EXPORT_CONSTANT(kTypeIdRegex);
    EXPORT_CONSTANT(kTypeIdWideString);
  }
}<|endoftext|>


<commit_before>#include "util.hpp"
#include "system.hpp"
#include "system/net.hpp"

#include <boost/asio.hpp>
#include <boost/asio/yield.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/system/error_code.hpp>
#include <boost/optional.hpp>
#include <boost/operators.hpp>

#include <algorithm>
#include <chrono>
#include <iostream>
#include <memory>
#include <string>
//#include <thread>
#include <utility>

namespace Net {

	static void sleep_for(deadline_timer &dt, short ms_wait = 500) {
		static const auto delay =
			boost::posix_time::milliseconds(ms_wait);
		dt.expires_from_now(delay);
		dt.wait();
	}

	// TODO
	struct cotask;

	struct channel:
	std::enable_shared_from_this<channel> {
		TCP::socket sock;
		template<typename T>
		channel& read(T &t) {
			auto scoped = shared_from_this();
			sock.async_read_some(
				buffer(ibuf, page_size::value),
				[&, this, scoped] (error_code ec, std::size_t len) {
					if(ec) return;
					if(len > 0) t.emplace_back(ibuf, len);
					read(t);
				});
			return *this;
		}
		channel& write(short bytes = page_size::value) {
			auto scoped = shared_from_this();
			sock.async_write_some(buffer(obuf, strlen(obuf)),
				[&, this, scoped] (error_code ec, std::size_t len) {
					if(ec) return;
					write();
				});
			return *this;
		}
		channel(io_service &svc, TCP::socket socket):
			sock(std::move(socket)), svc(svc) {}
	private:
		io_service &svc;
		page ibuf, obuf;
	};

	template<typename T>
	struct agent {
		agent(io_service &svc):
			sock(svc), svc(svc) {}
	protected:
		page ibuf, obuf;
		TCP::socket sock;
		io_service &svc;
		std::deque<std::string> lines;
	};

	struct server:
	public agent<server>,
	std::enable_shared_from_this<server> {
		server(io_service &svc, short port): agent(svc),
			acc(svc, std::move(TCP::endpoint(TCP::v4(), port))) {}
		// Async (accept and recurse) and return
		void accept(void) {
			auto scoped = shared_from_this();
			acc.async_accept(sock,
				[&, this, scoped] (error_code ec) {
					if(ec) return;
					std::make_shared<channel>(svc, std::move(sock))
						-> read(lines).write();
					accept();
				});
		}
		// Async (flush and recurse) and return
		void flush(void) {
			auto scoped = shared_from_this();
			svc.post([&, this, scoped] {
				while(!lines.empty()) {
					std::cout << lines.front() << std::endl;
					lines.pop_front();
				}
				flush();
			});
		}
		// Start async processes and return
		void start(void) {
			accept();
			flush();
		}
	protected:
		TCP::acceptor acc;
	};

	struct client:
	public agent<client>,
	std::enable_shared_from_this<client> {
		void read(void) {
			auto scoped = shared_from_this();
			async_read(sock, buffer(ibuf),
				[&, this, scoped] (error_code ec, std::size_t len) {
					if(ec) return;
					if(len > 0) {
						std::cout << "Client read \"" << len << "B: \""
							<< std::string(ibuf, len) << std::endl;
					}
					read();
				});
		}
		void write(void) {
			auto scoped = shared_from_this();
			const char *msg = "Same message";
			std::copy(msg, msg+strlen(msg), obuf);
			async_write(sock, buffer(obuf, strlen(obuf)),
				[&, this, scoped] (error_code ec, std::size_t len) {
					if(ec) return;
					write();
				});
		}
		void start(int max_attempts = 3, int attempts = 0) {
			send("Hello, world!");
			try {
				auto scoped = shared_from_this();
				sock.async_connect(
					TCP::endpoint(TCP::v4(), port),
					[&, this, scoped] (const error_code &ec) {
						if(ec) return;
						read();
						write();
					});
			} catch(std::exception &e) {
				std::cout << e.what() << std::endl;
				attempts++;
				if(attempts < max_attempts) {
					start(max_attempts, attempts);
				}
			}
		}
		client(io_service &svc, short port):
		agent(svc), port(port), res(svc) {}
	private:
		void send(const char *msg) {
			std::copy(msg, msg+strlen(msg), obuf);
		}
		short port;
		TCP::resolver res;
	};
}
<commit_msg>Added nested namespace; some minor edits<commit_after>#include "util.hpp"
#include "system.hpp"
#include "system/net.hpp"

#include <boost/asio.hpp>
#include <boost/asio/yield.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/system/error_code.hpp>
#include <boost/optional.hpp>
#include <boost/operators.hpp>

#include <algorithm>
#include <chrono>
#include <iostream>
#include <memory>
#include <string>
#include <utility>

#include <functional>

namespace System {
	namespace Net {

		static void sleep_for(deadline_timer &dt, short ms_wait = 500) {
			static const auto delay =
				boost::posix_time::milliseconds(ms_wait);
			dt.expires_from_now(delay);
			dt.wait();
		}

		struct channel:
		public std::enable_shared_from_this<channel> {
			TCP::socket sock;
			template<typename T>
			channel& read(T &t) {
				auto scoped = shared_from_this();
				sock.async_read_some(
					buffer(ibuf, page_size::value),
					[&, this, scoped] (error_code ec, std::size_t len) {
						if(ec) return;
						if(len > 0) t.emplace_back(ibuf, len);
						read(t);
					});
				return *this;
			}
			channel& write(short bytes = page_size::value) {
				auto scoped = shared_from_this();
				sock.async_write_some(buffer(obuf, strlen(obuf)),
					[&, this, scoped] (error_code ec, std::size_t len) {
						if(ec) return;
						write();
					});
				return *this;
			}
			channel(io_service &svc, TCP::socket socket):
				sock(std::move(socket)), svc(svc) {}
		private:
			io_service &svc;
			page ibuf, obuf;
		};

		template<class C>
		struct agent {
			agent(io_service &svc):
				sock(svc), svc(svc) {}
		protected:
			page ibuf, obuf;
			TCP::socket sock;
			io_service &svc;
			std::deque<std::string> lines;
		};

		struct server: public agent<server>,
		std::enable_shared_from_this<server> {
			server(io_service &svc, short port):
				agent<server>(svc),
				acc(svc, std::move(TCP::endpoint(TCP::v4(), port))) {}
			/// Async (accept and recurse) and return
			void accept(void) {
				auto scoped = shared_from_this();
				acc.async_accept(sock,
					[&, this, scoped] (error_code ec) {
						if(ec) return;
						std::make_shared<channel>(svc, std::move(sock))
							-> read(lines).write();
						accept();
					});
			}
			/// Async (flush and recurse) and return
			void flush(void) {
				auto scoped = shared_from_this();
				svc.post([&, this, scoped] {
					while(!lines.empty()) {
						std::cout << lines.front() << std::endl;
						lines.pop_front();
					}
					flush();
				});
			}
			/// Start async processes and return
			void start(void) {
				accept();
				flush();
			}
		protected:
			TCP::acceptor acc;
		};

		struct client: public agent<client>,
		std::enable_shared_from_this<client> {
			void read(void) {
				auto scoped = shared_from_this();
				async_read(sock, buffer(ibuf),
					[&, this, scoped] (error_code ec, std::size_t len) {
						if(ec) return;
						if(len > 0) {
							std::cout << "Client read \"" << len << "B: \""
								<< std::string(ibuf, len) << std::endl;
						}
						read();
					});
			}
			void write(void) {
				auto scoped = shared_from_this();
				const char *msg = "Same message";
				std::copy(msg, msg+strlen(msg), obuf);
				async_write(sock, buffer(obuf, strlen(obuf)),
					[&, this, scoped] (error_code ec, std::size_t len) {
						if(ec) return;
						write();
					});
			}
			void start(int max_attempts = 3, int attempts = 0) {
				send("Hello, world!");
				try {
					auto scoped = shared_from_this();
					sock.async_connect(
						TCP::endpoint(TCP::v4(), port),
						[&, this, scoped] (const error_code &ec) {
							if(ec) return;
							read();
							write();
						});
				} catch(std::exception &e) {
					std::cout << e.what() << std::endl;
					attempts++;
					if(attempts < max_attempts) {
						start(max_attempts, attempts);
					}
				}
			}
			client(io_service &svc, short port):
			agent<client>(svc), port(port), res(svc) {}
		private:
			void send(const char *msg) {
				std::copy(msg, msg+strlen(msg), obuf);
			}
			short port;
			TCP::resolver res;
		};
	}
}
<|endoftext|>


<commit_before>/***************************************************************************
    copyright (C) 2003      Adam Geitgey <adam@rootnode.org>
                  2003      Sven Leiber <s.leiber@web.de>
                  2000-2001 Matthias Ettrich <ettrich@kde.org>
                  2000-2001 Matthias Elter   <elter@kde.org>
                  2001      Carsten Pfeiffer <pfeiffer@kde.org>
                  2001      Martijn Klingens <mklingens@yahoo.com>
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "systemtray.h"

#include <qobject.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kwinmodule.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <kwin.h>

#include <qpopupmenu.h>
#include <qdragobject.h>
#include <qlayout.h>
#include <qstringlist.h>
#include <qpixmap.h>

#include <X11/Xlib.h>

Systemtray::Systemtray(QWidget* parent)
  : QWidget(parent,0,0)
{
  setBackgroundOrigin(ParentOrigin);
  setBackgroundMode(FixedPixmap);
  m_Wins.setAutoDelete(true);
}

Systemtray::~Systemtray()
{
  m_Wins.clear();
}

void Systemtray::updateBackgroundPixmap ( const QPixmap & pixmap) {
  QXEmbed *emb;
  setPaletteBackgroundPixmap (pixmap);
    for (emb = m_Wins.first(); emb != 0L; emb = m_Wins.next()) {

    //Stupid stupid stupid work around for annoying bug
    //QXEmbed ignores setBackgroundOrigin(AncestorOrigin)....
    QPixmap bug = QPixmap(emb->size());
    bitBlt(&bug, 0, 0, &pixmap, emb->parentWidget()->x()+emb->x(),  emb->parentWidget()->y()+emb->y(), emb->width(), emb->height(),Qt::CopyROP, false);
    emb->setPaletteBackgroundPixmap (bug);

  }

    QPoint topPoint = mapToGlobal(QPoint(0,0));
    Window hack = XCreateSimpleWindow(qt_xdisplay(), winId(), 0,0, width(), height(), 0, 0, 0);
    XRaiseWindow(qt_xdisplay(), hack);
    XMapWindow(qt_xdisplay(), hack);
    XUnmapWindow(qt_xdisplay(), hack);
    XDestroyWindow(qt_xdisplay(), hack);
}

void Systemtray::initSystray( void )
{
  bool existing = false;
  //bool content = false;
  Display *display = qt_xdisplay();
  no_of_systray_windows = 0;

  kwin_module = new KWinModule();
  systemTrayWindows = kwin_module->systemTrayWindows();
  for (QValueList<WId>::ConstIterator it = systemTrayWindows.begin(); it!=systemTrayWindows.end(); it++)
  {
    no_of_systray_windows++;
    QXEmbed *emb;

    emb = new QXEmbed(this);
    emb->setBackgroundMode(FixedPixmap);

    emb->setAutoDelete(false);

    connect(emb, SIGNAL(embeddedWindowDestroyed()), SLOT(updateTrayWindows()));

    m_Wins.append(emb);

    emb->embed(*it);
    emb->resize(24, 24);
    emb->show();
    existing = true;
  }

  updateTrayWindows();

  connect(kwin_module, SIGNAL(systemTrayWindowAdded(WId)), SLOT(systemTrayWindowAdded(WId)));
  connect(kwin_module, SIGNAL(systemTrayWindowRemoved(WId)), SLOT(systemTrayWindowRemoved(WId)));

  QCString screenstr;
  screenstr.setNum(qt_xscreen());
  QCString trayatom = "_NET_SYSTEM_TRAY_S" + screenstr;

  net_system_tray_selection = XInternAtom( display, trayatom, false );
  net_system_tray_opcode = XInternAtom( display, "_NET_SYSTEM_TRAY_OPCODE", false );

  // Acquire system tray
  XSetSelectionOwner( display,
    net_system_tray_selection,
    winId(),
    CurrentTime );

  WId root = qt_xrootwin();

  if (XGetSelectionOwner(display, net_system_tray_selection) == winId())
  {
    XClientMessageEvent xev;

    xev.type = ClientMessage;
    xev.window = root;

    xev.message_type = XInternAtom(display, "MANAGER", false);
    xev.format = 32;

    xev.data.l[0] = CurrentTime;
    xev.data.l[1] = net_system_tray_selection;
    xev.data.l[2] = winId();
    xev.data.l[3] = 0;       /* Manager specific data */
    xev.data.l[4] = 0;       /* Manager specific data */

    XSendEvent( display, root, false, StructureNotifyMask, (XEvent *)&xev );
  }
}

void Systemtray::updateTrayWindows( void )
{
  QXEmbed *emb;

  emb = m_Wins.first();
  while ((emb = m_Wins.current()) != 0L)
  {
    WId wid = emb->embeddedWinId();
    if ((wid == 0) || !kwin_module->systemTrayWindows().contains(wid) )
      m_Wins.remove(emb);
    else
      m_Wins.next();
  }
  layoutSystray();
}
void Systemtray::layoutSystray()
{
  int i = 0, a = 0;

  QXEmbed* emb;
  int x = 0;
  int count = 0;

  //How many systray icons can fit on a line?
  int aa = width() / 24;

  if(aa < 1)
  {
    /* The place is to small to display a icon we make than one line with
       icons that we display at the top */
    aa = 1;
  }

  for (emb = m_Wins.first(); emb != 0L; emb = m_Wins.next()) {
    x = 2+i*24;

    emb->move(a*24, x);
    a++;

    if(a+1 > aa) {
      a = 0;
      i++;
    }

    count++;
    emb->repaint();
  }
}

void Systemtray::systemTrayWindowAdded( WId w )
{
  //bool content = false;
  QXEmbed *emb;
  no_of_systray_windows++;
  emit updated();

  emb = new QXEmbed(this);

  emb->setAutoDelete(false);
  //emb->setBackgroundMode(X11ParentRelative);
  emb->setBackgroundMode(FixedPixmap);
  connect(emb, SIGNAL(embeddedWindowDestroyed()), SLOT(updateTrayWindows()));
  m_Wins.append(emb);

  emb->embed(w);
  emb->resize(24, 24);
  emb->show();

  layoutSystray();
}

void Systemtray::systemTrayWindowRemoved(WId)
{
  no_of_systray_windows--;
  emit updated();
  updateTrayWindows();
}

int Systemtray::getCurrentWindowCount()
{
  return no_of_systray_windows;
}

#include "systemtray.moc"
<commit_msg>Fix postincremental<commit_after>/***************************************************************************
    copyright (C) 2003      Adam Geitgey <adam@rootnode.org>
                  2003      Sven Leiber <s.leiber@web.de>
                  2000-2001 Matthias Ettrich <ettrich@kde.org>
                  2000-2001 Matthias Elter   <elter@kde.org>
                  2001      Carsten Pfeiffer <pfeiffer@kde.org>
                  2001      Martijn Klingens <mklingens@yahoo.com>
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "systemtray.h"

#include <qobject.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kwinmodule.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <kwin.h>

#include <qpopupmenu.h>
#include <qdragobject.h>
#include <qlayout.h>
#include <qstringlist.h>
#include <qpixmap.h>

#include <X11/Xlib.h>

Systemtray::Systemtray(QWidget* parent)
  : QWidget(parent,0,0)
{
  setBackgroundOrigin(ParentOrigin);
  setBackgroundMode(FixedPixmap);
  m_Wins.setAutoDelete(true);
}

Systemtray::~Systemtray()
{
  m_Wins.clear();
}

void Systemtray::updateBackgroundPixmap ( const QPixmap & pixmap) {
  QXEmbed *emb;
  setPaletteBackgroundPixmap (pixmap);
    for (emb = m_Wins.first(); emb != 0L; emb = m_Wins.next()) {

    //Stupid stupid stupid work around for annoying bug
    //QXEmbed ignores setBackgroundOrigin(AncestorOrigin)....
    QPixmap bug = QPixmap(emb->size());
    bitBlt(&bug, 0, 0, &pixmap, emb->parentWidget()->x()+emb->x(),  emb->parentWidget()->y()+emb->y(), emb->width(), emb->height(),Qt::CopyROP, false);
    emb->setPaletteBackgroundPixmap (bug);

  }

    QPoint topPoint = mapToGlobal(QPoint(0,0));
    Window hack = XCreateSimpleWindow(qt_xdisplay(), winId(), 0,0, width(), height(), 0, 0, 0);
    XRaiseWindow(qt_xdisplay(), hack);
    XMapWindow(qt_xdisplay(), hack);
    XUnmapWindow(qt_xdisplay(), hack);
    XDestroyWindow(qt_xdisplay(), hack);
}

void Systemtray::initSystray( void )
{
  bool existing = false;
  //bool content = false;
  Display *display = qt_xdisplay();
  no_of_systray_windows = 0;

  kwin_module = new KWinModule();
  systemTrayWindows = kwin_module->systemTrayWindows();
  QValueList<WId>::ConstIterator end(systemTrayWindows.end());
  for (QValueList<WId>::ConstIterator it = systemTrayWindows.begin(); it!=end; ++it)
  {
    no_of_systray_windows++;
    QXEmbed *emb;

    emb = new QXEmbed(this);
    emb->setBackgroundMode(FixedPixmap);

    emb->setAutoDelete(false);

    connect(emb, SIGNAL(embeddedWindowDestroyed()), SLOT(updateTrayWindows()));

    m_Wins.append(emb);

    emb->embed(*it);
    emb->resize(24, 24);
    emb->show();
    existing = true;
  }

  updateTrayWindows();

  connect(kwin_module, SIGNAL(systemTrayWindowAdded(WId)), SLOT(systemTrayWindowAdded(WId)));
  connect(kwin_module, SIGNAL(systemTrayWindowRemoved(WId)), SLOT(systemTrayWindowRemoved(WId)));

  QCString screenstr;
  screenstr.setNum(qt_xscreen());
  QCString trayatom = "_NET_SYSTEM_TRAY_S" + screenstr;

  net_system_tray_selection = XInternAtom( display, trayatom, false );
  net_system_tray_opcode = XInternAtom( display, "_NET_SYSTEM_TRAY_OPCODE", false );

  // Acquire system tray
  XSetSelectionOwner( display,
    net_system_tray_selection,
    winId(),
    CurrentTime );

  WId root = qt_xrootwin();

  if (XGetSelectionOwner(display, net_system_tray_selection) == winId())
  {
    XClientMessageEvent xev;

    xev.type = ClientMessage;
    xev.window = root;

    xev.message_type = XInternAtom(display, "MANAGER", false);
    xev.format = 32;

    xev.data.l[0] = CurrentTime;
    xev.data.l[1] = net_system_tray_selection;
    xev.data.l[2] = winId();
    xev.data.l[3] = 0;       /* Manager specific data */
    xev.data.l[4] = 0;       /* Manager specific data */

    XSendEvent( display, root, false, StructureNotifyMask, (XEvent *)&xev );
  }
}

void Systemtray::updateTrayWindows( void )
{
  QXEmbed *emb;

  emb = m_Wins.first();
  while ((emb = m_Wins.current()) != 0L)
  {
    WId wid = emb->embeddedWinId();
    if ((wid == 0) || !kwin_module->systemTrayWindows().contains(wid) )
      m_Wins.remove(emb);
    else
      m_Wins.next();
  }
  layoutSystray();
}
void Systemtray::layoutSystray()
{
  int i = 0, a = 0;

  QXEmbed* emb;
  int x = 0;
  int count = 0;

  //How many systray icons can fit on a line?
  int aa = width() / 24;

  if(aa < 1)
  {
    /* The place is to small to display a icon we make than one line with
       icons that we display at the top */
    aa = 1;
  }

  for (emb = m_Wins.first(); emb != 0L; emb = m_Wins.next()) {
    x = 2+i*24;

    emb->move(a*24, x);
    a++;

    if(a+1 > aa) {
      a = 0;
      i++;
    }

    count++;
    emb->repaint();
  }
}

void Systemtray::systemTrayWindowAdded( WId w )
{
  //bool content = false;
  QXEmbed *emb;
  no_of_systray_windows++;
  emit updated();

  emb = new QXEmbed(this);

  emb->setAutoDelete(false);
  //emb->setBackgroundMode(X11ParentRelative);
  emb->setBackgroundMode(FixedPixmap);
  connect(emb, SIGNAL(embeddedWindowDestroyed()), SLOT(updateTrayWindows()));
  m_Wins.append(emb);

  emb->embed(w);
  emb->resize(24, 24);
  emb->show();

  layoutSystray();
}

void Systemtray::systemTrayWindowRemoved(WId)
{
  no_of_systray_windows--;
  emit updated();
  updateTrayWindows();
}

int Systemtray::getCurrentWindowCount()
{
  return no_of_systray_windows;
}

#include "systemtray.moc"
<|endoftext|>


<commit_before>// Copyright (c) 2013, Cloudera, inc.
// All rights reserved.

#include <boost/foreach.hpp>
#include <boost/thread/locks.hpp>
#include <boost/thread/mutex.hpp>
#include <glog/logging.h>
#include <algorithm>

#include "gutil/map-util.h"
#include "gutil/mathlimits.h"
#include "gutil/port.h"
#include "gutil/stringprintf.h"
#include "gutil/strings/strcat.h"
#include "gutil/strings/substitute.h"
#include "server/logical_clock.h"
#include "tablet/mvcc.h"
#include "util/countdown_latch.h"
#include "util/stopwatch.h"

namespace kudu { namespace tablet {

MvccManager::MvccManager(const scoped_refptr<server::Clock>& clock)
  : earliest_in_flight_(Timestamp::kMax),
    clock_(clock) {
  cur_snap_.all_committed_before_ = Timestamp::kInitialTimestamp;
  cur_snap_.none_committed_at_or_after_ = Timestamp::kInitialTimestamp;
}

Timestamp MvccManager::StartTransaction() {
  while (true) {
    Timestamp now = clock_->Now();
    boost::lock_guard<LockType> l(lock_);
    if (PREDICT_TRUE(InitTransactionUnlocked(now))) {
      return now;
    }
  }
}

Timestamp MvccManager::StartTransactionAtLatest() {
  boost::lock_guard<LockType> l(lock_);
  Timestamp now_latest = clock_->NowLatest();
  while (PREDICT_FALSE(!InitTransactionUnlocked(now_latest))) {
    now_latest = clock_->NowLatest();
  }

  // If in debug mode enforce that transactions have monotonically increasing
  // timestamps at all times
#ifndef NDEBUG
  if (!timestamps_in_flight_.empty()) {
    Timestamp max(*std::max_element(timestamps_in_flight_.begin(),
                                    timestamps_in_flight_.end()));
    CHECK_EQ(max.value(), now_latest.value());
  }
#endif

  return now_latest;
}

Status MvccManager::StartTransactionAtTimestamp(Timestamp timestamp) {
  boost::lock_guard<LockType> l(lock_);
  if (PREDICT_FALSE(cur_snap_.IsCommitted(timestamp))) {
    return Status::IllegalState(
        strings::Substitute("Timestamp: $0 is already committed.", timestamp.value()));
  }
  if (!InitTransactionUnlocked(timestamp)) {
    return Status::IllegalState(
        strings::Substitute("There is already a transaction with timestamp: $0 in flight.",
                            timestamp.value()));
  }
  return Status::OK();
}

bool MvccManager::InitTransactionUnlocked(const Timestamp& timestamp) {
  // Ensure that we didn't mark the given timestamp as "safe" in between
  // acquiring the time and taking the lock. This allows us to acquire timestamps
  // outside of the MVCC lock.
  if (PREDICT_FALSE(cur_snap_.all_committed_before_.CompareTo(timestamp) > 0)) {
    return false;
  }
  // Since transactions only commit once they are in the past, and new
  // transactions always start either in the current time or the future,
  // we should never be trying to start a new transaction at the same time
  // as an already-committed one.
  DCHECK(!cur_snap_.IsCommitted(timestamp))
    << "Trying to start a new txn at already-committed timestamp "
    << timestamp.ToString()
    << " cur_snap_: " << cur_snap_.ToString();

  if (timestamp.CompareTo(earliest_in_flight_) < 0) {
    earliest_in_flight_ = timestamp;
  }

  return timestamps_in_flight_.insert(timestamp.value()).second;
}

void MvccManager::CommitTransaction(Timestamp timestamp) {
  boost::lock_guard<LockType> l(lock_);
  bool was_earliest = false;
  CommitTransactionUnlocked(timestamp, &was_earliest);

  if (was_earliest) {
    // This is an 'online' commit so adjust the 'all_committed_before_' watermark
    // up to clock_->Now().
    AdjustSafeTime(clock_->Now());
  }
}

Timestamp MvccManager::GetSafeTime() {
  boost::lock_guard<LockType> l(lock_);
  return cur_snap_.all_committed_before_;
}

void MvccManager::OfflineCommitTransaction(Timestamp timestamp) {
  boost::lock_guard<LockType> l(lock_);

  // Commit the transaction, but do not adjust 'all_committed_before_', that will
  // be done with a separate OfflineAdjustCurSnap() call.
  bool was_earliest = false;
  CommitTransactionUnlocked(timestamp, &was_earliest);
}

void MvccManager::CommitTransactionUnlocked(Timestamp timestamp,
                                            bool* was_earliest_in_flight) {
  DCHECK(clock_->IsAfter(timestamp))
    << "Trying to commit a transaction with a future timestamp: "
    << timestamp.ToString() << ". Current time: " << clock_->Stringify(clock_->Now());

  *was_earliest_in_flight = earliest_in_flight_ == timestamp;

  // Remove from our in-flight list.
  CHECK_EQ(timestamps_in_flight_.erase(timestamp.value()), 1)
    << "Trying to commit timestamp which isn't in the in-flight set: "
    << timestamp.ToString();

  // Add to snapshot's committed list
  cur_snap_.AddCommittedTimestamp(timestamp);

  // If we're committing the earliest transaction that was in flight,
  // update our cached value.
  if (*was_earliest_in_flight) {
    if (timestamps_in_flight_.empty()) {
      earliest_in_flight_ = Timestamp::kMax;
    } else {
      earliest_in_flight_ = Timestamp(*std::min_element(timestamps_in_flight_.begin(),
                                                        timestamps_in_flight_.end()));
    }
  }
}

void MvccManager::OfflineAdjustSafeTime(Timestamp safe_time) {
  boost::lock_guard<LockType> l(lock_);
  AdjustSafeTime(safe_time);
}

// Remove any elements from 'v' which are < the given watermark.
static void FilterTimestamps(std::vector<Timestamp::val_type>* v,
                             Timestamp::val_type watermark) {
  int j = 0;
  for (int i = 0; i < v->size(); i++) {
    if ((*v)[i] >= watermark) {
      (*v)[j++] = (*v)[i];
    }
  }
  v->resize(j);
}

void MvccManager::AdjustSafeTime(Timestamp safe_time) {

  // There are two possibilities:
  //
  // 1) We still have an in-flight transaction earlier than 'safe_time'.
  //    In this case, we update the watermark to that transaction's timestamp.
  //
  // 2) There are no in-flight transactions earlier than 'safe_time'.
  //    (There may still be in-flight transactions with future timestamps due to
  //    commit-wait transactions which start in the future). In this case, we update
  //    the watermark to 'safe_time', since we know that no new transactions can start
  //    with an earlier timestamp.
  //
  // In either case, we have to add the newly committed ts only if it remains higher
  // than the new watermark.

  if (earliest_in_flight_.CompareTo(safe_time) < 0) {
    cur_snap_.all_committed_before_ = earliest_in_flight_;
  } else {
    cur_snap_.all_committed_before_ = safe_time;
  }

  // Filter out any committed timestamps that now fall below the watermark
  FilterTimestamps(&cur_snap_.committed_timestamps_, cur_snap_.all_committed_before_.value());

  // it may also have unblocked some waiters.
  // Check if someone is waiting for transactions to be committed.
  if (PREDICT_FALSE(!waiters_.empty())) {
    vector<WaitingState*>::iterator iter = waiters_.begin();
    while (iter != waiters_.end()) {
      WaitingState* waiter = *iter;
      if (AreAllTransactionsCommittedUnlocked(waiter->timestamp)) {
        iter = waiters_.erase(iter);
        waiter->latch->CountDown();
        continue;
      }
      iter++;
    }
  }
}

void MvccManager::WaitUntilAllCommitted(Timestamp ts) const {
  CountDownLatch latch(1);
  WaitingState waiting_state;
  {
    boost::lock_guard<LockType> l(lock_);
    if (AreAllTransactionsCommittedUnlocked(ts)) return;
    waiting_state.timestamp = ts;
    waiting_state.latch = &latch;
    waiters_.push_back(&waiting_state);
  }
  waiting_state.latch->Wait();
}

bool MvccManager::AreAllTransactionsCommittedUnlocked(Timestamp ts) const {
  if (timestamps_in_flight_.empty()) {
    // If nothing is in-flight, then check the clock. If the timestamp is in the past,
    // we know that no new uncommitted transactions may start before this ts.
    return ts.CompareTo(clock_->Now()) <= 0;
  }
  // If some transactions are in flight, then check the in-flight list.
  return !cur_snap_.MayHaveUncommittedTransactionsAtOrBefore(ts);
}

void MvccManager::TakeSnapshot(MvccSnapshot *snap) const {
  boost::lock_guard<LockType> l(lock_);
  *snap = cur_snap_;
}

void MvccManager::WaitForCleanSnapshotAtTimestamp(Timestamp timestamp, MvccSnapshot *snap) const {
  DCHECK(clock_->IsAfter(timestamp))
    << "timestamp " << timestamp.ToString() << " must be in the past";
  WaitUntilAllCommitted(timestamp);
  *snap = MvccSnapshot(timestamp);
}

void MvccManager::WaitForCleanSnapshot(MvccSnapshot* snap) const {
  WaitForCleanSnapshotAtTimestamp(clock_->Now(), snap);
}

void MvccManager::WaitForAllInFlightToCommit() const {
  Timestamp wait_for;

  {
    boost::lock_guard<LockType> l(lock_);
    if (timestamps_in_flight_.empty()) {
      return;
    }

    // We could wait exactly for the set of in-flight transactions to commit,
    // but that's a little trickier to implement. So for now, we just wait
    // until all transactions lower than the current highest timestamp.
    // This may wait longer than necessary if new transactions start with
    // a lower timestamp, but that's OK - there is no "wait for the minimum
    // amount of time" guarantee in this API.
    wait_for = Timestamp(*std::max_element(timestamps_in_flight_.begin(),
                                           timestamps_in_flight_.end()));
  }

  WaitUntilAllCommitted(wait_for);
}

bool MvccManager::AreAllTransactionsCommitted(Timestamp ts) const {
  boost::lock_guard<LockType> l(lock_);
  return AreAllTransactionsCommittedUnlocked(ts);
}

int MvccManager::CountTransactionsInFlight() const {
  boost::lock_guard<LockType> l(lock_);
  return timestamps_in_flight_.size();
}

Timestamp MvccManager::GetSafeTimestamp() const {
  boost::lock_guard<LockType> l(lock_);
  return cur_snap_.all_committed_before_;
}

void MvccManager::GetInFlightTransactionTimestamps(std::vector<Timestamp>* timestamps) const {
  boost::lock_guard<LockType> l(lock_);
  timestamps->reserve(timestamps_in_flight_.size());
  BOOST_FOREACH(const Timestamp::val_type val, timestamps_in_flight_) {
    timestamps->push_back(Timestamp(val));
  }
}

MvccManager::~MvccManager() {
  CHECK(waiters_.empty());
}

////////////////////////////////////////////////////////////
// MvccSnapshot
////////////////////////////////////////////////////////////

MvccSnapshot::MvccSnapshot()
  : all_committed_before_(Timestamp::kInitialTimestamp),
    none_committed_at_or_after_(Timestamp::kInitialTimestamp) {
}

MvccSnapshot::MvccSnapshot(const MvccManager &manager) {
  manager.TakeSnapshot(this);
}

MvccSnapshot::MvccSnapshot(const Timestamp& timestamp)
  : all_committed_before_(timestamp),
    none_committed_at_or_after_(timestamp) {
 }

MvccSnapshot MvccSnapshot::CreateSnapshotIncludingAllTransactions() {
  return MvccSnapshot(Timestamp::kMax);
}

MvccSnapshot MvccSnapshot::CreateSnapshotIncludingNoTransactions() {
  return MvccSnapshot(Timestamp::kMin);
}

bool MvccSnapshot::IsCommittedFallback(const Timestamp& timestamp) const {
  BOOST_FOREACH(const Timestamp::val_type& v, committed_timestamps_) {
    if (v == timestamp.value()) return true;
  }

  return false;
}

bool MvccSnapshot::MayHaveCommittedTransactionsAtOrAfter(const Timestamp& timestamp) const {
  return timestamp.CompareTo(none_committed_at_or_after_) < 0;
}

bool MvccSnapshot::MayHaveUncommittedTransactionsAtOrBefore(const Timestamp& timestamp) const {
  return timestamp.CompareTo(all_committed_before_) >= 0;
}

std::string MvccSnapshot::ToString() const {
  string ret("MvccSnapshot[committed={T|");

  if (committed_timestamps_.size() == 0) {
    StrAppend(&ret, "T < ", all_committed_before_.ToString(),"}]");
    return ret;
  }
  StrAppend(&ret, "T < ", all_committed_before_.ToString(),
            " or (T in {");

  bool first = true;
  BOOST_FOREACH(Timestamp::val_type t, committed_timestamps_) {
    if (!first) {
      ret.push_back(',');
    }
    first = false;
    StrAppend(&ret, t);
  }
  ret.append("})}]");
  return ret;
}

void MvccSnapshot::AddCommittedTimestamps(const std::vector<Timestamp>& timestamps) {
  BOOST_FOREACH(const Timestamp& ts, timestamps) {
    AddCommittedTimestamp(ts);
  }
}

void MvccSnapshot::AddCommittedTimestamp(Timestamp timestamp) {
  if (IsCommitted(timestamp)) return;

  committed_timestamps_.push_back(timestamp.value());

  // If this is a new upper bound commit mark, update it.
  if (none_committed_at_or_after_.CompareTo(timestamp) <= 0) {
    none_committed_at_or_after_ = Timestamp(timestamp.value() + 1);
  }
}

////////////////////////////////////////////////////////////
// ScopedTransaction
////////////////////////////////////////////////////////////
ScopedTransaction::ScopedTransaction(MvccManager *mgr, TimestampAssignmentType assignment_type)
  : committed_(false),
    manager_(DCHECK_NOTNULL(mgr)),
    assignment_type_(assignment_type) {

  switch (assignment_type_) {
    case NOW: {
      timestamp_ = mgr->StartTransaction();
      break;
    }
    case NOW_LATEST: {
      timestamp_ = mgr->StartTransactionAtLatest();
      break;
    }
    default: {
      LOG(FATAL) << "Illegal TransactionAssignmentType. Only NOW and NOW_LATEST are supported"
          " by this ctor.";
    }
  }
}

ScopedTransaction::ScopedTransaction(MvccManager *mgr, Timestamp timestamp)
  : committed_(false),
    manager_(DCHECK_NOTNULL(mgr)),
    assignment_type_(PRE_ASSIGNED),
    timestamp_(timestamp) {
  CHECK_OK(mgr->StartTransactionAtTimestamp(timestamp));
}

ScopedTransaction::~ScopedTransaction() {
  if (!committed_) {
    Commit();
  }
}

void ScopedTransaction::Commit() {
  switch (assignment_type_) {
    case NOW:
    case NOW_LATEST: {
      manager_->CommitTransaction(timestamp_);
      break;
    }
    case PRE_ASSIGNED: {
      manager_->OfflineCommitTransaction(timestamp_);
      break;
    }
    default: {
      LOG(FATAL) << "Unexpected transaction assignment type.";
    }
  }

  committed_ = true;
}

} // namespace tablet
} // namespace kudu
<commit_msg>Add a dummy return to MvccManager::StartTransaction() to avoid IDE/compiler warnings.<commit_after>// Copyright (c) 2013, Cloudera, inc.
// All rights reserved.

#include <boost/foreach.hpp>
#include <boost/thread/locks.hpp>
#include <boost/thread/mutex.hpp>
#include <glog/logging.h>
#include <algorithm>

#include "gutil/map-util.h"
#include "gutil/mathlimits.h"
#include "gutil/port.h"
#include "gutil/stringprintf.h"
#include "gutil/strings/strcat.h"
#include "gutil/strings/substitute.h"
#include "server/logical_clock.h"
#include "tablet/mvcc.h"
#include "util/countdown_latch.h"
#include "util/stopwatch.h"

namespace kudu { namespace tablet {

MvccManager::MvccManager(const scoped_refptr<server::Clock>& clock)
  : earliest_in_flight_(Timestamp::kMax),
    clock_(clock) {
  cur_snap_.all_committed_before_ = Timestamp::kInitialTimestamp;
  cur_snap_.none_committed_at_or_after_ = Timestamp::kInitialTimestamp;
}

Timestamp MvccManager::StartTransaction() {
  while (true) {
    Timestamp now = clock_->Now();
    boost::lock_guard<LockType> l(lock_);
    if (PREDICT_TRUE(InitTransactionUnlocked(now))) {
      return now;
    }
  }
  // dummy return to avoid compiler warnings
  LOG(FATAL) << "Unreachable, added to avoid compiler warning.";
  return Timestamp::kInvalidTimestamp;
}

Timestamp MvccManager::StartTransactionAtLatest() {
  boost::lock_guard<LockType> l(lock_);
  Timestamp now_latest = clock_->NowLatest();
  while (PREDICT_FALSE(!InitTransactionUnlocked(now_latest))) {
    now_latest = clock_->NowLatest();
  }

  // If in debug mode enforce that transactions have monotonically increasing
  // timestamps at all times
#ifndef NDEBUG
  if (!timestamps_in_flight_.empty()) {
    Timestamp max(*std::max_element(timestamps_in_flight_.begin(),
                                    timestamps_in_flight_.end()));
    CHECK_EQ(max.value(), now_latest.value());
  }
#endif

  return now_latest;
}

Status MvccManager::StartTransactionAtTimestamp(Timestamp timestamp) {
  boost::lock_guard<LockType> l(lock_);
  if (PREDICT_FALSE(cur_snap_.IsCommitted(timestamp))) {
    return Status::IllegalState(
        strings::Substitute("Timestamp: $0 is already committed.", timestamp.value()));
  }
  if (!InitTransactionUnlocked(timestamp)) {
    return Status::IllegalState(
        strings::Substitute("There is already a transaction with timestamp: $0 in flight.",
                            timestamp.value()));
  }
  return Status::OK();
}

bool MvccManager::InitTransactionUnlocked(const Timestamp& timestamp) {
  // Ensure that we didn't mark the given timestamp as "safe" in between
  // acquiring the time and taking the lock. This allows us to acquire timestamps
  // outside of the MVCC lock.
  if (PREDICT_FALSE(cur_snap_.all_committed_before_.CompareTo(timestamp) > 0)) {
    return false;
  }
  // Since transactions only commit once they are in the past, and new
  // transactions always start either in the current time or the future,
  // we should never be trying to start a new transaction at the same time
  // as an already-committed one.
  DCHECK(!cur_snap_.IsCommitted(timestamp))
    << "Trying to start a new txn at already-committed timestamp "
    << timestamp.ToString()
    << " cur_snap_: " << cur_snap_.ToString();

  if (timestamp.CompareTo(earliest_in_flight_) < 0) {
    earliest_in_flight_ = timestamp;
  }

  return timestamps_in_flight_.insert(timestamp.value()).second;
}

void MvccManager::CommitTransaction(Timestamp timestamp) {
  boost::lock_guard<LockType> l(lock_);
  bool was_earliest = false;
  CommitTransactionUnlocked(timestamp, &was_earliest);

  if (was_earliest) {
    // This is an 'online' commit so adjust the 'all_committed_before_' watermark
    // up to clock_->Now().
    AdjustSafeTime(clock_->Now());
  }
}

Timestamp MvccManager::GetSafeTime() {
  boost::lock_guard<LockType> l(lock_);
  return cur_snap_.all_committed_before_;
}

void MvccManager::OfflineCommitTransaction(Timestamp timestamp) {
  boost::lock_guard<LockType> l(lock_);

  // Commit the transaction, but do not adjust 'all_committed_before_', that will
  // be done with a separate OfflineAdjustCurSnap() call.
  bool was_earliest = false;
  CommitTransactionUnlocked(timestamp, &was_earliest);
}

void MvccManager::CommitTransactionUnlocked(Timestamp timestamp,
                                            bool* was_earliest_in_flight) {
  DCHECK(clock_->IsAfter(timestamp))
    << "Trying to commit a transaction with a future timestamp: "
    << timestamp.ToString() << ". Current time: " << clock_->Stringify(clock_->Now());

  *was_earliest_in_flight = earliest_in_flight_ == timestamp;

  // Remove from our in-flight list.
  CHECK_EQ(timestamps_in_flight_.erase(timestamp.value()), 1)
    << "Trying to commit timestamp which isn't in the in-flight set: "
    << timestamp.ToString();

  // Add to snapshot's committed list
  cur_snap_.AddCommittedTimestamp(timestamp);

  // If we're committing the earliest transaction that was in flight,
  // update our cached value.
  if (*was_earliest_in_flight) {
    if (timestamps_in_flight_.empty()) {
      earliest_in_flight_ = Timestamp::kMax;
    } else {
      earliest_in_flight_ = Timestamp(*std::min_element(timestamps_in_flight_.begin(),
                                                        timestamps_in_flight_.end()));
    }
  }
}

void MvccManager::OfflineAdjustSafeTime(Timestamp safe_time) {
  boost::lock_guard<LockType> l(lock_);
  AdjustSafeTime(safe_time);
}

// Remove any elements from 'v' which are < the given watermark.
static void FilterTimestamps(std::vector<Timestamp::val_type>* v,
                             Timestamp::val_type watermark) {
  int j = 0;
  for (int i = 0; i < v->size(); i++) {
    if ((*v)[i] >= watermark) {
      (*v)[j++] = (*v)[i];
    }
  }
  v->resize(j);
}

void MvccManager::AdjustSafeTime(Timestamp safe_time) {

  // There are two possibilities:
  //
  // 1) We still have an in-flight transaction earlier than 'safe_time'.
  //    In this case, we update the watermark to that transaction's timestamp.
  //
  // 2) There are no in-flight transactions earlier than 'safe_time'.
  //    (There may still be in-flight transactions with future timestamps due to
  //    commit-wait transactions which start in the future). In this case, we update
  //    the watermark to 'safe_time', since we know that no new transactions can start
  //    with an earlier timestamp.
  //
  // In either case, we have to add the newly committed ts only if it remains higher
  // than the new watermark.

  if (earliest_in_flight_.CompareTo(safe_time) < 0) {
    cur_snap_.all_committed_before_ = earliest_in_flight_;
  } else {
    cur_snap_.all_committed_before_ = safe_time;
  }

  // Filter out any committed timestamps that now fall below the watermark
  FilterTimestamps(&cur_snap_.committed_timestamps_, cur_snap_.all_committed_before_.value());

  // it may also have unblocked some waiters.
  // Check if someone is waiting for transactions to be committed.
  if (PREDICT_FALSE(!waiters_.empty())) {
    vector<WaitingState*>::iterator iter = waiters_.begin();
    while (iter != waiters_.end()) {
      WaitingState* waiter = *iter;
      if (AreAllTransactionsCommittedUnlocked(waiter->timestamp)) {
        iter = waiters_.erase(iter);
        waiter->latch->CountDown();
        continue;
      }
      iter++;
    }
  }
}

void MvccManager::WaitUntilAllCommitted(Timestamp ts) const {
  CountDownLatch latch(1);
  WaitingState waiting_state;
  {
    boost::lock_guard<LockType> l(lock_);
    if (AreAllTransactionsCommittedUnlocked(ts)) return;
    waiting_state.timestamp = ts;
    waiting_state.latch = &latch;
    waiters_.push_back(&waiting_state);
  }
  waiting_state.latch->Wait();
}

bool MvccManager::AreAllTransactionsCommittedUnlocked(Timestamp ts) const {
  if (timestamps_in_flight_.empty()) {
    // If nothing is in-flight, then check the clock. If the timestamp is in the past,
    // we know that no new uncommitted transactions may start before this ts.
    return ts.CompareTo(clock_->Now()) <= 0;
  }
  // If some transactions are in flight, then check the in-flight list.
  return !cur_snap_.MayHaveUncommittedTransactionsAtOrBefore(ts);
}

void MvccManager::TakeSnapshot(MvccSnapshot *snap) const {
  boost::lock_guard<LockType> l(lock_);
  *snap = cur_snap_;
}

void MvccManager::WaitForCleanSnapshotAtTimestamp(Timestamp timestamp, MvccSnapshot *snap) const {
  DCHECK(clock_->IsAfter(timestamp))
    << "timestamp " << timestamp.ToString() << " must be in the past";
  WaitUntilAllCommitted(timestamp);
  *snap = MvccSnapshot(timestamp);
}

void MvccManager::WaitForCleanSnapshot(MvccSnapshot* snap) const {
  WaitForCleanSnapshotAtTimestamp(clock_->Now(), snap);
}

void MvccManager::WaitForAllInFlightToCommit() const {
  Timestamp wait_for;

  {
    boost::lock_guard<LockType> l(lock_);
    if (timestamps_in_flight_.empty()) {
      return;
    }

    // We could wait exactly for the set of in-flight transactions to commit,
    // but that's a little trickier to implement. So for now, we just wait
    // until all transactions lower than the current highest timestamp.
    // This may wait longer than necessary if new transactions start with
    // a lower timestamp, but that's OK - there is no "wait for the minimum
    // amount of time" guarantee in this API.
    wait_for = Timestamp(*std::max_element(timestamps_in_flight_.begin(),
                                           timestamps_in_flight_.end()));
  }

  WaitUntilAllCommitted(wait_for);
}

bool MvccManager::AreAllTransactionsCommitted(Timestamp ts) const {
  boost::lock_guard<LockType> l(lock_);
  return AreAllTransactionsCommittedUnlocked(ts);
}

int MvccManager::CountTransactionsInFlight() const {
  boost::lock_guard<LockType> l(lock_);
  return timestamps_in_flight_.size();
}

Timestamp MvccManager::GetSafeTimestamp() const {
  boost::lock_guard<LockType> l(lock_);
  return cur_snap_.all_committed_before_;
}

void MvccManager::GetInFlightTransactionTimestamps(std::vector<Timestamp>* timestamps) const {
  boost::lock_guard<LockType> l(lock_);
  timestamps->reserve(timestamps_in_flight_.size());
  BOOST_FOREACH(const Timestamp::val_type val, timestamps_in_flight_) {
    timestamps->push_back(Timestamp(val));
  }
}

MvccManager::~MvccManager() {
  CHECK(waiters_.empty());
}

////////////////////////////////////////////////////////////
// MvccSnapshot
////////////////////////////////////////////////////////////

MvccSnapshot::MvccSnapshot()
  : all_committed_before_(Timestamp::kInitialTimestamp),
    none_committed_at_or_after_(Timestamp::kInitialTimestamp) {
}

MvccSnapshot::MvccSnapshot(const MvccManager &manager) {
  manager.TakeSnapshot(this);
}

MvccSnapshot::MvccSnapshot(const Timestamp& timestamp)
  : all_committed_before_(timestamp),
    none_committed_at_or_after_(timestamp) {
 }

MvccSnapshot MvccSnapshot::CreateSnapshotIncludingAllTransactions() {
  return MvccSnapshot(Timestamp::kMax);
}

MvccSnapshot MvccSnapshot::CreateSnapshotIncludingNoTransactions() {
  return MvccSnapshot(Timestamp::kMin);
}

bool MvccSnapshot::IsCommittedFallback(const Timestamp& timestamp) const {
  BOOST_FOREACH(const Timestamp::val_type& v, committed_timestamps_) {
    if (v == timestamp.value()) return true;
  }

  return false;
}

bool MvccSnapshot::MayHaveCommittedTransactionsAtOrAfter(const Timestamp& timestamp) const {
  return timestamp.CompareTo(none_committed_at_or_after_) < 0;
}

bool MvccSnapshot::MayHaveUncommittedTransactionsAtOrBefore(const Timestamp& timestamp) const {
  return timestamp.CompareTo(all_committed_before_) >= 0;
}

std::string MvccSnapshot::ToString() const {
  string ret("MvccSnapshot[committed={T|");

  if (committed_timestamps_.size() == 0) {
    StrAppend(&ret, "T < ", all_committed_before_.ToString(),"}]");
    return ret;
  }
  StrAppend(&ret, "T < ", all_committed_before_.ToString(),
            " or (T in {");

  bool first = true;
  BOOST_FOREACH(Timestamp::val_type t, committed_timestamps_) {
    if (!first) {
      ret.push_back(',');
    }
    first = false;
    StrAppend(&ret, t);
  }
  ret.append("})}]");
  return ret;
}

void MvccSnapshot::AddCommittedTimestamps(const std::vector<Timestamp>& timestamps) {
  BOOST_FOREACH(const Timestamp& ts, timestamps) {
    AddCommittedTimestamp(ts);
  }
}

void MvccSnapshot::AddCommittedTimestamp(Timestamp timestamp) {
  if (IsCommitted(timestamp)) return;

  committed_timestamps_.push_back(timestamp.value());

  // If this is a new upper bound commit mark, update it.
  if (none_committed_at_or_after_.CompareTo(timestamp) <= 0) {
    none_committed_at_or_after_ = Timestamp(timestamp.value() + 1);
  }
}

////////////////////////////////////////////////////////////
// ScopedTransaction
////////////////////////////////////////////////////////////
ScopedTransaction::ScopedTransaction(MvccManager *mgr, TimestampAssignmentType assignment_type)
  : committed_(false),
    manager_(DCHECK_NOTNULL(mgr)),
    assignment_type_(assignment_type) {

  switch (assignment_type_) {
    case NOW: {
      timestamp_ = mgr->StartTransaction();
      break;
    }
    case NOW_LATEST: {
      timestamp_ = mgr->StartTransactionAtLatest();
      break;
    }
    default: {
      LOG(FATAL) << "Illegal TransactionAssignmentType. Only NOW and NOW_LATEST are supported"
          " by this ctor.";
    }
  }
}

ScopedTransaction::ScopedTransaction(MvccManager *mgr, Timestamp timestamp)
  : committed_(false),
    manager_(DCHECK_NOTNULL(mgr)),
    assignment_type_(PRE_ASSIGNED),
    timestamp_(timestamp) {
  CHECK_OK(mgr->StartTransactionAtTimestamp(timestamp));
}

ScopedTransaction::~ScopedTransaction() {
  if (!committed_) {
    Commit();
  }
}

void ScopedTransaction::Commit() {
  switch (assignment_type_) {
    case NOW:
    case NOW_LATEST: {
      manager_->CommitTransaction(timestamp_);
      break;
    }
    case PRE_ASSIGNED: {
      manager_->OfflineCommitTransaction(timestamp_);
      break;
    }
    default: {
      LOG(FATAL) << "Unexpected transaction assignment type.";
    }
  }

  committed_ = true;
}

} // namespace tablet
} // namespace kudu
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <math.h>

#include "ev3api.h"
#include "Point.h"
#include "FieldMap.h"
#include "InOutManager.h"
#include "ParticleFilter.h"

// 正規分布でsigmaに指定した範囲内の値を取り出す
double Particle::NormalDistribution(double sigma) {
	double alpha = (double)rand()/RAND_MAX;
    double beta = (double)rand()/RAND_MAX * M_PI * 2;
    double tmp = sin(beta);
    return sigma * sqrt(-2 * log(alpha)) * tmp;
}

// 座標を更新して、尤度を再計算する
void Particle::Update(int8_t leftMotorCount, int8_t rightMotorCount)
{
	// 車輪直径(mm)
	double TireDiameter = 81.6;

	// 左右車輪間の距離(mm)
	double d = 128;

	// 左車輪の移動距離
	double Tl = TireDiameter * M_PI * leftMotorCount / 360.0;

	// 右車輪の移動距離
	double Tr = TireDiameter * M_PI * rightMotorCount / 360.0;

	// モータエンコーダ値の変化量
	double D = (Tl + Tr) / 2.0;

	// 角度の変化量
	double theta = (Tr - Tl) / d;

	// ラジアンに変換した前回の角度
	double theta0 = RobotAngle * M_PI / 180.0;

	// 0 - 360度の範囲に変更
	if(RobotAngle + (theta / M_PI * 180.0) > 360) {
		RobotAngle = RobotAngle + (theta / M_PI * 180.0) - 360;
	}else if(RobotAngle + (theta / M_PI * 180.0) < 0) {
		RobotAngle = 360 + RobotAngle +(theta / M_PI * 180.0);
	}else {
		RobotAngle += (theta / M_PI * 180.0);
	}

	// 変化量を、正規分布の値を加味して算出
	// double sinc_theta = fabs(theta/2.0)<1.0e-10 ? 1.0 : sin(theta/2.0)/(theta/2.0);
	// double deltaX = D * cos(theta0 + (theta / 2.0)) * sinc_theta;
	// double deltaY = D * sin(theta0 + (theta / 2.0)) * sinc_theta;
	double deltaX = D * cos(theta0 + (theta / 2.0));
	double deltaY = D * sin(theta0 + (theta / 2.0));

	RobotPoint.X += deltaX;
	RobotPoint.Y -= deltaY;

	// 地図上の色情報を取得
	HSLColor mapColor = FieldMap::GetInstance()->GetHSLColor(RobotPoint.X, RobotPoint.Y);

	// センサから得た色情報を元に、尤度を定義
	Likelihood = ColorDecision::GetLikelihoodLuminosity(mapColor.Luminosity, InOutManager::GetInstance()->HSLValue.Luminosity);
}

// 指定した座標で粒子を撒きなおす
void Particle::Reset(Point* newPoint, double newAngle, double pointSigma, double angleSigma)
{
	// 正規分布の値を加味する
	RobotPoint.X = newPoint->X + NormalDistribution(pointSigma);
	RobotPoint.Y = newPoint->Y + NormalDistribution(pointSigma);
	RobotAngle = newAngle + NormalDistribution(angleSigma);

	Likelihood = 0;
}

// 中心値を指定して、パーティクルを散布する
void ParticleFilter::Resampling(Point* newPoint, double newAngle, double pointSigma, double angleSigma)
{
	// 全ての粒子に対しt、中心座標を指定した再散布を行う
	for(Particle* p: ParticleArray) {
		p->Reset(newPoint, newAngle, pointSigma, angleSigma);
	}
}

// パーティクルに対して、座標のアップデートを行う
void ParticleFilter::UpdateParticle(int8_t leftMotorCount, int8_t rightMotorCount)
{
	// すべての粒子に対して状態遷移を実施する
	for(Particle*  p: ParticleArray) {
		p->Update(leftMotorCount,  rightMotorCount);
	}

}

// パーティクルのうち、尤度の高い物の平均値を元に、
// 自身の状態を更新する
void ParticleFilter::Localize()
{
	// 尤度が閾値より高い粒子は、すべて平均化の対象とする。
	const double min = 0.1;

	std::vector<Particle*> pVector;

	for(Particle* p : ParticleArray) {
		if(p->Likelihood > min) pVector.push_back(p);
	}

	double x = 0, y = 0, angle = 0;

	// 尤度の高い粒子が存在しない場合には、すべての粒子を平均化
	if(pVector.size() == 0)	{
		for(Particle* p  : ParticleArray) {
			x += p->RobotPoint.X;
			y += p->RobotPoint.Y;
			angle += p->RobotAngle;
		}

		x /= PARTICLE_COUNT;
		y /= PARTICLE_COUNT;
		angle /= PARTICLE_COUNT;
	} else {
		// 閾値以上の粒子を平均化
		for(Particle* p : pVector) {
			x += p->RobotPoint.X;
			y += p->RobotPoint.Y;
			angle += p->RobotAngle;
		}

		x /= pVector.size();
		y /= pVector.size();
		angle /= pVector.size();
	}

	// atan2の出力範囲が-pi ~ piのため、0-360の範囲に修正
	if(angle < 0) {
		angle = 360 + angle;
	}

	// 算出した平均値でフィールドを更新
	RobotPoint.X = x;
	RobotPoint.Y = y;
	RobotAngle = angle;
}
<commit_msg>sinc(theta/2)を3次までテイラー展開することでオドメトリ精度向上（今までは0次）<commit_after>#include <stdlib.h>
#include <math.h>

#include "ev3api.h"
#include "Point.h"
#include "FieldMap.h"
#include "InOutManager.h"
#include "ParticleFilter.h"

// 正規分布でsigmaに指定した範囲内の値を取り出す
double Particle::NormalDistribution(double sigma) {
	double alpha = (double)rand()/RAND_MAX;
    double beta = (double)rand()/RAND_MAX * M_PI * 2;
    double tmp = sin(beta);
    return sigma * sqrt(-2 * log(alpha)) * tmp;
}

// 座標を更新して、尤度を再計算する
void Particle::Update(int8_t leftMotorCount, int8_t rightMotorCount)
{
	// 車輪直径(mm)
	double TireDiameter = 81.6;

	// 左右車輪間の距離(mm)
	double d = 128;

	// 左車輪の移動距離
	double Tl = TireDiameter * M_PI * leftMotorCount / 360.0;

	// 右車輪の移動距離
	double Tr = TireDiameter * M_PI * rightMotorCount / 360.0;

	// モータエンコーダ値の変化量
	double D = (Tl + Tr) / 2.0;

	// 角度の変化量
	double theta = (Tr - Tl) / d;

	// ラジアンに変換した前回の角度
	double theta0 = RobotAngle * M_PI / 180.0;

	// 0 - 360度の範囲に変更
	if(RobotAngle + (theta / M_PI * 180.0) > 360) {
		RobotAngle = RobotAngle + (theta / M_PI * 180.0) - 360;
	}else if(RobotAngle + (theta / M_PI * 180.0) < 0) {
		RobotAngle = 360 + RobotAngle +(theta / M_PI * 180.0);
	}else {
		RobotAngle += (theta / M_PI * 180.0);
	}

	// 変化量を、正規分布の値を加味して算出
	double sinc = 1 - theta*theta/24.0 * (1 - theta*theta/80.0 * (1 - theta*theta/168.0));	//sinc(theta/2)を3次までテイラー展開
	// double sinc_theta = fabs(theta/2.0)<1.0e-10 ? 1.0 : sin(theta/2.0)/(theta/2.0);
	double deltaX = D * cos(theta0 + (theta / 2.0)) * sinc;
	double deltaY = D * sin(theta0 + (theta / 2.0)) * sinc;
	// double deltaX = D * cos(theta0 + (theta / 2.0));
	// double deltaY = D * sin(theta0 + (theta / 2.0));

	RobotPoint.X += deltaX;
	RobotPoint.Y -= deltaY;

	// 地図上の色情報を取得
	HSLColor mapColor = FieldMap::GetInstance()->GetHSLColor(RobotPoint.X, RobotPoint.Y);

	// センサから得た色情報を元に、尤度を定義
	Likelihood = ColorDecision::GetLikelihoodLuminosity(mapColor.Luminosity, InOutManager::GetInstance()->HSLValue.Luminosity);
}

// 指定した座標で粒子を撒きなおす
void Particle::Reset(Point* newPoint, double newAngle, double pointSigma, double angleSigma)
{
	// 正規分布の値を加味する
	RobotPoint.X = newPoint->X + NormalDistribution(pointSigma);
	RobotPoint.Y = newPoint->Y + NormalDistribution(pointSigma);
	RobotAngle = newAngle + NormalDistribution(angleSigma);

	Likelihood = 0;
}

// 中心値を指定して、パーティクルを散布する
void ParticleFilter::Resampling(Point* newPoint, double newAngle, double pointSigma, double angleSigma)
{
	// 全ての粒子に対しt、中心座標を指定した再散布を行う
	for(Particle* p: ParticleArray) {
		p->Reset(newPoint, newAngle, pointSigma, angleSigma);
	}
}

// パーティクルに対して、座標のアップデートを行う
void ParticleFilter::UpdateParticle(int8_t leftMotorCount, int8_t rightMotorCount)
{
	// すべての粒子に対して状態遷移を実施する
	for(Particle*  p: ParticleArray) {
		p->Update(leftMotorCount,  rightMotorCount);
	}

}

// パーティクルのうち、尤度の高い物の平均値を元に、
// 自身の状態を更新する
void ParticleFilter::Localize()
{
	// 尤度が閾値より高い粒子は、すべて平均化の対象とする。
	const double min = 0.1;

	std::vector<Particle*> pVector;

	for(Particle* p : ParticleArray) {
		if(p->Likelihood > min) pVector.push_back(p);
	}

	double x = 0, y = 0, angle = 0;

	// 尤度の高い粒子が存在しない場合には、すべての粒子を平均化
	if(pVector.size() == 0)	{
		for(Particle* p  : ParticleArray) {
			x += p->RobotPoint.X;
			y += p->RobotPoint.Y;
			angle += p->RobotAngle;
		}

		x /= PARTICLE_COUNT;
		y /= PARTICLE_COUNT;
		angle /= PARTICLE_COUNT;
	} else {
		// 閾値以上の粒子を平均化
		for(Particle* p : pVector) {
			x += p->RobotPoint.X;
			y += p->RobotPoint.Y;
			angle += p->RobotAngle;
		}

		x /= pVector.size();
		y /= pVector.size();
		angle /= pVector.size();
	}

	// atan2の出力範囲が-pi ~ piのため、0-360の範囲に修正
	if(angle < 0) {
		angle = 360 + angle;
	}

	// 算出した平均値でフィールドを更新
	RobotPoint.X = x;
	RobotPoint.Y = y;
	RobotAngle = angle;
}
<|endoftext|>


<commit_before>/*
 * bacteria-core, core for cellular automaton
 * Copyright (C) 2016 Pavel Dolgov
 *
 * See the LICENSE file for terms of use.
 */

#include <boost/test/unit_test.hpp>

#include "Model.hpp"

template<typename Func>
static void checkErrorHandling(
    Implementation::Model* model,
    Func model_method
) {
    // range errors: test all combinations of
    // "wrong" (outside of correct range) arguments
    // Max_index: 0; min_index: 0
    for (int arg1 = -1; arg1 <= 1; arg1++) {
        for (int arg2 = -1; arg2 <= 1; arg2++) {
            if ((arg1 != 0) || (arg2 != 0)) {
                // (0, 0) is correct
                BOOST_REQUIRE_THROW(
                    ((*model).*model_method)(arg1, arg2), Exception
                );
            }
        }
    }
    // "dead" error
    // (attempt to do something with dead bacterium)
    model->kill(0, 0);
    BOOST_REQUIRE_THROW(
        ((*model).*model_method)(0, 0), Exception
    );
}

#define CREATE_NEW \
    model->createNewByCoordinates( \
        coordinates, \
        DEFAULT_MASS, \
        0, \
        0, \
        0 \
    );

static Abstract::Point createInBaseCoordinates(
    Implementation::Model* model
) {
    Abstract::Point coordinates(0, 0);
    model->createNewByCoordinates(
        coordinates,
        DEFAULT_MASS,
        0,
        0,
        0
    );
    return coordinates;
}

static Implementation::Model* createBaseModel(
    int bacteria = 0,
    int teams = 1
) {
    Implementation::Model* model =
        Abstract::makeModel<Implementation::Model>(
            MIN_WIDTH,
            MIN_HEIGHT,
            bacteria,
            teams
        );
    return model;
}

BOOST_AUTO_TEST_CASE (bacteria_number_test) {
    Implementation::Model* model = createBaseModel();
    int bacteria_number = model->getBacteriaNumber(0);
    BOOST_REQUIRE(bacteria_number == 0);
    createInBaseCoordinates(model);
    bacteria_number = model->getBacteriaNumber(0);
    BOOST_REQUIRE(bacteria_number == 1);
    // range errors
    BOOST_REQUIRE_THROW(model->getBacteriaNumber(-1), Exception);
    BOOST_REQUIRE_THROW(model->getBacteriaNumber(1), Exception);
    delete model;
}

BOOST_AUTO_TEST_CASE (get_mass_test) {
    Implementation::Model* model = createBaseModel(1, 1);
    int mass = model->getMass(0, 0);
    BOOST_REQUIRE(mass == DEFAULT_MASS);
    checkErrorHandling(model, &Implementation::Model::getMass);
    delete model;
}

BOOST_AUTO_TEST_CASE (height_test) {
    Implementation::Model* model = createBaseModel();
    BOOST_REQUIRE(model->getHeight() == MIN_HEIGHT);
    delete model;
}

BOOST_AUTO_TEST_CASE (width_test) {
    Implementation::Model* model = createBaseModel();
    BOOST_REQUIRE(model->getWidth() == MIN_WIDTH);
    delete model;
}

BOOST_AUTO_TEST_CASE (kill_test) {
    Implementation::Model* model = createBaseModel();
    Abstract::Point coordinates = createInBaseCoordinates(model);
    model->kill(0, 0);
    Abstract::CellState state = model->cellState(coordinates);
    BOOST_REQUIRE(state == Abstract::EMPTY);
    // error handling checks
    createInBaseCoordinates(model);
    // FIXME test doesn't work correctly without this function call.
    // The solution is to use set instead of vector in model.
    model->clearBeforeMove(0);
    checkErrorHandling(model, &Implementation::Model::kill);
    delete model;
}

BOOST_AUTO_TEST_CASE (create_coordinates_test) {
    Implementation::Model* model = createBaseModel();
    Abstract::Point coordinates = createInBaseCoordinates(model);
    Abstract::CellState state = model->cellState(coordinates);
    BOOST_REQUIRE(state == Abstract::BACTERIUM);
    delete model;
}

BOOST_AUTO_TEST_CASE (kill_coordinates_test) {
    Implementation::Model* model = createBaseModel();
    Abstract::Point coordinates = createInBaseCoordinates(model);
    model->killByCoordinates(coordinates);
    Abstract::CellState state = model->cellState(coordinates);
    BOOST_REQUIRE(state == Abstract::EMPTY);
    delete model;
}
<commit_msg>Use CREATE_NEW in createInBaseCoordinates()<commit_after>/*
 * bacteria-core, core for cellular automaton
 * Copyright (C) 2016 Pavel Dolgov
 *
 * See the LICENSE file for terms of use.
 */

#include <boost/test/unit_test.hpp>

#include "Model.hpp"

template<typename Func>
static void checkErrorHandling(
    Implementation::Model* model,
    Func model_method
) {
    // range errors: test all combinations of
    // "wrong" (outside of correct range) arguments
    // Max_index: 0; min_index: 0
    for (int arg1 = -1; arg1 <= 1; arg1++) {
        for (int arg2 = -1; arg2 <= 1; arg2++) {
            if ((arg1 != 0) || (arg2 != 0)) {
                // (0, 0) is correct
                BOOST_REQUIRE_THROW(
                    ((*model).*model_method)(arg1, arg2), Exception
                );
            }
        }
    }
    // "dead" error
    // (attempt to do something with dead bacterium)
    model->kill(0, 0);
    BOOST_REQUIRE_THROW(
        ((*model).*model_method)(0, 0), Exception
    );
}

#define CREATE_NEW \
    model->createNewByCoordinates( \
        coordinates, \
        DEFAULT_MASS, \
        0, \
        0, \
        0 \
    );

static Abstract::Point createInBaseCoordinates(
    Implementation::Model* model
) {
    Abstract::Point coordinates(0, 0);
    CREATE_NEW
    return coordinates;
}

static Implementation::Model* createBaseModel(
    int bacteria = 0,
    int teams = 1
) {
    Implementation::Model* model =
        Abstract::makeModel<Implementation::Model>(
            MIN_WIDTH,
            MIN_HEIGHT,
            bacteria,
            teams
        );
    return model;
}

BOOST_AUTO_TEST_CASE (bacteria_number_test) {
    Implementation::Model* model = createBaseModel();
    int bacteria_number = model->getBacteriaNumber(0);
    BOOST_REQUIRE(bacteria_number == 0);
    createInBaseCoordinates(model);
    bacteria_number = model->getBacteriaNumber(0);
    BOOST_REQUIRE(bacteria_number == 1);
    // range errors
    BOOST_REQUIRE_THROW(model->getBacteriaNumber(-1), Exception);
    BOOST_REQUIRE_THROW(model->getBacteriaNumber(1), Exception);
    delete model;
}

BOOST_AUTO_TEST_CASE (get_mass_test) {
    Implementation::Model* model = createBaseModel(1, 1);
    int mass = model->getMass(0, 0);
    BOOST_REQUIRE(mass == DEFAULT_MASS);
    checkErrorHandling(model, &Implementation::Model::getMass);
    delete model;
}

BOOST_AUTO_TEST_CASE (height_test) {
    Implementation::Model* model = createBaseModel();
    BOOST_REQUIRE(model->getHeight() == MIN_HEIGHT);
    delete model;
}

BOOST_AUTO_TEST_CASE (width_test) {
    Implementation::Model* model = createBaseModel();
    BOOST_REQUIRE(model->getWidth() == MIN_WIDTH);
    delete model;
}

BOOST_AUTO_TEST_CASE (kill_test) {
    Implementation::Model* model = createBaseModel();
    Abstract::Point coordinates = createInBaseCoordinates(model);
    model->kill(0, 0);
    Abstract::CellState state = model->cellState(coordinates);
    BOOST_REQUIRE(state == Abstract::EMPTY);
    // error handling checks
    createInBaseCoordinates(model);
    // FIXME test doesn't work correctly without this function call.
    // The solution is to use set instead of vector in model.
    model->clearBeforeMove(0);
    checkErrorHandling(model, &Implementation::Model::kill);
    delete model;
}

BOOST_AUTO_TEST_CASE (create_coordinates_test) {
    Implementation::Model* model = createBaseModel();
    Abstract::Point coordinates = createInBaseCoordinates(model);
    Abstract::CellState state = model->cellState(coordinates);
    BOOST_REQUIRE(state == Abstract::BACTERIUM);
    delete model;
}

BOOST_AUTO_TEST_CASE (kill_coordinates_test) {
    Implementation::Model* model = createBaseModel();
    Abstract::Point coordinates = createInBaseCoordinates(model);
    model->killByCoordinates(coordinates);
    Abstract::CellState state = model->cellState(coordinates);
    BOOST_REQUIRE(state == Abstract::EMPTY);
    delete model;
}
<|endoftext|>


<commit_before>// @(#)root/meta:$Name:  $:$Id: $
// Author: Philippe Canal 08/05/2002

#include "Rtypes.h"
#include "TNamed.h"
#include "TClass.h"

namespace ROOT {

   const InitBehavior *DefineBehavior(void * /*parent_type*/,
                                      void * /*actual_type*/) {

      // This function loads the default behavior for the
      // loading of classes.

      static DefaultInitBehavior Default;
      return &Default;
   }

   GenericClassInfo::GenericClassInfo(const char *fullClassname,
                                      const char *declFileName, Int_t declFileLine,
                                      const type_info &info, const InitBehavior  *action,
                                      void *showmembers, VoidFuncPtr_t dictionary,
                                      IsAFunc_t isa, Int_t pragmabits)
      : fAction(action), fClassName(fullClassname),
        fDeclFileName(declFileName), fDeclFileLine(declFileLine),
        fDictionary(dictionary), fInfo(info), fIsA(isa), fShowMembers(showmembers),
        fVersion(1)
   {
      Init(pragmabits);
   }

   GenericClassInfo::GenericClassInfo(const char *fullClassname, Int_t version,
                                      const char *declFileName, Int_t declFileLine,
                                      const type_info &info, const InitBehavior  *action,
                                      void* showmembers,  VoidFuncPtr_t dictionary,
                                      IsAFunc_t isa, Int_t pragmabits)
      : fAction(action), fClassName(fullClassname),
        fDeclFileName(declFileName), fDeclFileLine(declFileLine),
        fDictionary(dictionary), fInfo(info), fIsA(isa), fShowMembers(showmembers),
        fVersion(version) {
      Init(pragmabits);
   }

   GenericClassInfo::GenericClassInfo(const char *fullClassname, Int_t version,
                                      const char *declFileName, Int_t declFileLine,
                                      const type_info &info, const InitBehavior  *action,
                                      void* showmembers,  VoidFuncPtr_t dictionary,
                                      Int_t pragmabits)
      : fAction(action), fClassName(fullClassname),
        fDeclFileName(declFileName), fDeclFileLine(declFileLine),
        fDictionary(dictionary), fInfo(info), fIsA(0), fShowMembers(showmembers),
        fVersion(version) {
      Init(pragmabits);
   }

   GenericClassInfo::GenericClassInfo(const char *fullClassname, Int_t version,
                                      const char *declFileName, Int_t declFileLine,
                                      const type_info &info, const InitBehavior  *action,
                                      VoidFuncPtr_t dictionary,
                                      Int_t pragmabits)
      : fAction(action), fClassName(fullClassname),
        fDeclFileName(declFileName), fDeclFileLine(declFileLine),
        fDictionary(dictionary), fInfo(info), fIsA(0), fShowMembers(0),
        fVersion(version) {
      Init(pragmabits);
   }

   void GenericClassInfo::Init(Int_t pragmabits) {
      if (!fAction) return;
      GetAction().Register(fClassName,
                           fVersion,
                           fInfo, // typeid(RootClass),
                           fDictionary,
                           pragmabits);
   }

   GenericClassInfo::~GenericClassInfo() { if (fAction) GetAction().Unregister(GetClassName()); }

   const InitBehavior &GenericClassInfo::GetAction() {
      //if (!fAction) {
      //   RootClass *ptr = 0;
      //   fAction = DefineBehavior(ptr, ptr);
      //}
      return *fAction;
   }

   TClass *GenericClassInfo::GetClass() {
      if (!fClass && fAction) {
         fClass = GetAction().CreateClass(GetClassName(),
                                          GetVersion(),
                                          GetInfo(),
                                          GetIsA(),
                                          (ShowMembersFunc_t)GetShowMembers(),
                                          GetDeclFileName(),
                                          GetImplFileName(),
                                          GetDeclFileLine(),
                                          GetImplFileLine());
      }
      return fClass;
   }

   const char *GenericClassInfo::GetClassName() {
      return fClassName;
   }

   const type_info &GenericClassInfo::GetInfo() {
      return fInfo;
   }

   void *GenericClassInfo::GetShowMembers() {
      return fShowMembers;
   }

   void GenericClassInfo::SetFromTemplate() {
      TNamed *info = ROOT::RegisterClassTemplate(GetClassName(), 0, 0);
      if (info) SetImplFile(info->GetTitle(), info->GetUniqueID());
   }

   int GenericClassInfo::SetImplFile(const char *file, Int_t line) {
      fImplFileName = file;
      fImplFileLine = line;
      if (fClass) fClass->AddImplFile(file,line);
      return 0;
   }

   Short_t GenericClassInfo::SetVersion(Short_t version) {
      ROOT::ResetClassVersion(fClass, GetClassName(),version);
      fVersion = version;
      return version;
   }

   const char *GenericClassInfo::GetDeclFileName() {
      return fDeclFileName;
   }

   Int_t GenericClassInfo::GetDeclFileLine() {
      return fDeclFileLine;
   }

   const char *GenericClassInfo::GetImplFileName() {
      if (!fImplFileName) SetFromTemplate();
      return fImplFileName;
   }

   Int_t GenericClassInfo::GetImplFileLine() {
      if (!fImplFileLine) SetFromTemplate();
      return fImplFileLine;
   }

   Int_t GenericClassInfo::GetVersion() {
      return fVersion;
   }

   TClass* GenericClassInfo::IsA(const void *obj) {
      return (GetIsA())(obj);
   }

   IsAFunc_t GenericClassInfo::GetIsA() { return fIsA; }

}
<commit_msg>make getters const and added copyright statement.<commit_after>// @(#)root/meta:$Name:  $:$Id: GenericClassInfo.cxx,v 1.1 2002/05/09 20:53:21 brun Exp $
// Author: Philippe Canal 08/05/2002

/*************************************************************************
 * Copyright (C) 1995-2002, Rene Brun, Fons Rademakers and al.           *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "Rtypes.h"
#include "TNamed.h"
#include "TClass.h"

namespace ROOT {

   const InitBehavior *DefineBehavior(void * /*parent_type*/,
                                      void * /*actual_type*/)
   {

      // This function loads the default behavior for the
      // loading of classes.

      static DefaultInitBehavior theDefault;
      return &theDefault;
   }

   GenericClassInfo::GenericClassInfo(const char *fullClassname,
                                      const char *declFileName, Int_t declFileLine,
                                      const type_info &info, const InitBehavior  *action,
                                      void *showmembers, VoidFuncPtr_t dictionary,
                                      IsAFunc_t isa, Int_t pragmabits)
      : fAction(action), fClassName(fullClassname),
        fDeclFileName(declFileName), fDeclFileLine(declFileLine),
        fDictionary(dictionary), fInfo(info), fIsA(isa), fShowMembers(showmembers),
        fVersion(1)
   {
      Init(pragmabits);
   }

   GenericClassInfo::GenericClassInfo(const char *fullClassname, Int_t version,
                                      const char *declFileName, Int_t declFileLine,
                                      const type_info &info, const InitBehavior  *action,
                                      void* showmembers,  VoidFuncPtr_t dictionary,
                                      IsAFunc_t isa, Int_t pragmabits)
      : fAction(action), fClassName(fullClassname),
        fDeclFileName(declFileName), fDeclFileLine(declFileLine),
        fDictionary(dictionary), fInfo(info), fIsA(isa), fShowMembers(showmembers),
        fVersion(version)
   {
      Init(pragmabits);
   }

   GenericClassInfo::GenericClassInfo(const char *fullClassname, Int_t version,
                                      const char *declFileName, Int_t declFileLine,
                                      const type_info &info, const InitBehavior  *action,
                                      void* showmembers,  VoidFuncPtr_t dictionary,
                                      Int_t pragmabits)
      : fAction(action), fClassName(fullClassname),
        fDeclFileName(declFileName), fDeclFileLine(declFileLine),
        fDictionary(dictionary), fInfo(info), fIsA(0), fShowMembers(showmembers),
        fVersion(version)
   {
      Init(pragmabits);
   }

   GenericClassInfo::GenericClassInfo(const char *fullClassname, Int_t version,
                                      const char *declFileName, Int_t declFileLine,
                                      const type_info &info, const InitBehavior  *action,
                                      VoidFuncPtr_t dictionary,
                                      Int_t pragmabits)
      : fAction(action), fClassName(fullClassname),
        fDeclFileName(declFileName), fDeclFileLine(declFileLine),
        fDictionary(dictionary), fInfo(info), fIsA(0), fShowMembers(0),
        fVersion(version)
   {
      Init(pragmabits);
   }

   void GenericClassInfo::Init(Int_t pragmabits)
   {
      if (!fAction) return;
      GetAction().Register(fClassName,
                           fVersion,
                           fInfo, // typeid(RootClass),
                           fDictionary,
                           pragmabits);
   }

   GenericClassInfo::~GenericClassInfo()
   {
      if (fAction) GetAction().Unregister(GetClassName());
   }

   const InitBehavior &GenericClassInfo::GetAction() const
   {
      return *fAction;
   }

   TClass *GenericClassInfo::GetClass()
   {
      if (!fClass && fAction) {
         fClass = GetAction().CreateClass(GetClassName(),
                                          GetVersion(),
                                          GetInfo(),
                                          GetIsA(),
                                          (ShowMembersFunc_t)GetShowMembers(),
                                          GetDeclFileName(),
                                          GetImplFileName(),
                                          GetDeclFileLine(),
                                          GetImplFileLine());
      }
      return fClass;
   }

   const char *GenericClassInfo::GetClassName() const
   {
      return fClassName;
   }

   const type_info &GenericClassInfo::GetInfo() const
   {
      return fInfo;
   }

   void *GenericClassInfo::GetShowMembers() const
   {
      return fShowMembers;
   }

   void GenericClassInfo::SetFromTemplate()
   {
      TNamed *info = ROOT::RegisterClassTemplate(GetClassName(), 0, 0);
      if (info) SetImplFile(info->GetTitle(), info->GetUniqueID());
   }

   Int_t GenericClassInfo::SetImplFile(const char *file, Int_t line)
   {
      fImplFileName = file;
      fImplFileLine = line;
      if (fClass) fClass->AddImplFile(file,line);
      return 0;
   }

   Short_t GenericClassInfo::SetVersion(Short_t version)
   {
      ROOT::ResetClassVersion(fClass, GetClassName(),version);
      fVersion = version;
      return version;
   }

   const char *GenericClassInfo::GetDeclFileName() const
   {
      return fDeclFileName;
   }

   Int_t GenericClassInfo::GetDeclFileLine() const
   {
      return fDeclFileLine;
   }

   const char *GenericClassInfo::GetImplFileName()
   {
      if (!fImplFileName) SetFromTemplate();
      return fImplFileName;
   }

   Int_t GenericClassInfo::GetImplFileLine()
   {
      if (!fImplFileLine) SetFromTemplate();
      return fImplFileLine;
   }

   Int_t GenericClassInfo::GetVersion() const
   {
      return fVersion;
   }

   TClass *GenericClassInfo::IsA(const void *obj)
   {
      return (GetIsA())(obj);
   }

   IsAFunc_t GenericClassInfo::GetIsA() const
   {
      return fIsA;
   }

}
<|endoftext|>


<commit_before>
#include "zorba/zorba_singlethread.h"

#include <iostream>

using namespace std;
using namespace xqp;

/*
	Using Zorba in single thread mode.
	This is a should fail example.
	It demonstrates how to retrieve and print error messages.
	You can find the error codes and error classes in zorba/errors/errors.h.
*/

string make_absolute_file_name(const char *target_file_name, const char *this_file_name);

int usecase5(int argc, char* argv[])
{
	bool original_throw_mode = ZorbaAlertsManager::setThrowExceptionsMode(true);
	//init the engine
	ZorbaSingleThread_t zorba_engine = ZorbaSingleThread::getInstance();
	XQuery_t				xquery;
	DynamicQueryContext_t		dctx;

	try{
		//create and compile a query with the static context
		xquery = zorba_engine->createQuery(".//book");

		dctx = zorba_engine->createDynamicContext();
	/*forget to set the context item
		//context item is set
		dctx->SetContextItemAsDocument(make_absolute_file_name("books.xml", __FILE__));
	*/

		//try to execute the query and serialize its result
		xquery->initExecution(dctx);
		xquery->serializeXML(std::cout);

		assert(false);//unreachable, should exit on error path
		return 1;
	}catch(ZorbaException &x)
	{
		//multiple errors and warnings might get fired
		//display all of them
		ZorbaAlertsManager_t err_manager = zorba_engine->getAlertsManagerForCurrentThread();
		err_manager->dumpAlerts(std::cout);
	}

	ZorbaAlertsManager::setThrowExceptionsMode(original_throw_mode);
	return 0;
}
<commit_msg>Removed file/folder<commit_after><|endoftext|>