<commit_before>#ifndef K3_UNIQPOLYBUF
#define K3_UNIQPOLYBUF

#include <unordered_set>

#if HAS_LIBDYNAMIC

#include <boost/serialization/array.hpp>
#include <boost/serialization/string.hpp>
#include <boost/functional/hash.hpp>

#include <yaml-cpp/yaml.h>
#include <rapidjson/document.h>
#include <csvpp/csv.h>
#include "serialization/Json.hpp"

#include "Common.hpp"
#include "collections/STLDataspace.hpp"
#include "collections/Collection.hpp"
#include "collections/FlatPolyBuffer.hpp"

namespace K3 {
namespace Libdynamic {

template<typename Ignore, typename Derived>
class UniquePolyBuffer;

//////////////////////////////////////////
//
// Buffer functors.

struct UPBValueProxy {
  UPBValueProxy(size_t o) : asOffset(true), offset(o) {}
  UPBValueProxy(char* p) : asOffset(false), elem(p) {}

  bool asOffset;
  union {
    char* elem;
    size_t offset;
  };
};

template<typename Tag>
using UPBKey = std::pair<Tag, UPBValueProxy>;

template<class Ignore, class T, typename Tag>
struct UPBEqual : std::binary_function<UPBKey<Tag>, UPBKey<Tag>, bool>
{
  using Container = typename FlatPolyBuffer<Ignore, T>::Container;
  using UPB = UniquePolyBuffer<Ignore, T>;
  using ExternalizerT = BufferExternalizer;
  using InternalizerT = BufferInternalizer;

  Container* container;
  ExternalizerT etl;
  InternalizerT itl;

  UPBEqual(UPB* c)
    : container(c->container.get()),
      etl(container->variable(), ExternalizerT::ExternalizeOp::Reuse),
      itl(container->variable())
  {}

  bool operator()(const UPBKey<Tag>& left, const UPBKey<Tag>& right) const {
    auto buffer = container->fixed();
    char* lp = left.second.asOffset? buffer_data(buffer) + left.second.offset : left.second.elem;
    char* rp = right.second.asOffset? buffer_data(buffer) + right.second.offset : right.second.elem;

    if ( !container->internalized ) {
      if ( left.second.asOffset ) { T::internalize(const_cast<InternalizerT&>(itl), left.first, lp); }
      if ( right.second.asOffset ) { T::internalize(const_cast<InternalizerT&>(itl), right.first, rp); }
    }

    bool r = T::equalelem(left.first, lp, right.first, rp);

    if ( !container->internalized ) {
      if ( left.second.asOffset ) { T::externalize(const_cast<ExternalizerT&>(etl), left.first, lp); }
      if ( right.second.asOffset ) { T::externalize(const_cast<ExternalizerT&>(etl), right.first, rp); }
    }
    return r;
  }
};

template<typename Ignore, typename T, typename Tag>
struct UPBHash : std::unary_function<UPBKey<Tag>, std::size_t>
{
  using Container = typename FlatPolyBuffer<Ignore, T>::Container;
  using UPB = UniquePolyBuffer<Ignore, T>;
  using ExternalizerT = BufferExternalizer;
  using InternalizerT = BufferInternalizer;

  Container* container;
  ExternalizerT etl;
  InternalizerT itl;

  UPBHash(UPB* c)
    : container(c->container.get()),
      etl(container->variable(), ExternalizerT::ExternalizeOp::Reuse),
      itl(container->variable())
  {}

  std::size_t operator()(const UPBKey<Tag>& k) const {
    std::hash<Tag> hash;
    size_t h1 = hash(k.first);
    auto buffer = container->fixed();
    char* p = k.second.asOffset? buffer_data(buffer) + k.second.offset : k.second.elem;
    if ( !container->internalized && k.second.asOffset ) {
      T::internalize(const_cast<InternalizerT&>(itl), k.first, p);
    }

    boost::hash_combine(h1, T::hashelem(k.first, p));

    if ( !container->internalized && k.second.asOffset ) {
      T::externalize(const_cast<ExternalizerT&>(etl), k.first, p);
    }
    return h1;
  }
};

//////////////////////////////////////////
//
// UniquePolyBuffer

template<class Ignore, class Derived>
class UniquePolyBuffer : public FlatPolyBuffer<Ignore, Derived> {
public:
  using Super = FlatPolyBuffer<Ignore, Derived>;
  using Tag = typename Super::Tag;

  using FContainer = typename Super::FContainer;
  using VContainer = typename Super::VContainer;
  using TContainer = typename Super::TContainer;

  UniquePolyBuffer()
    : Super(), comparator(this), hasher(this), keys(10, hasher, comparator)
  {}

  UniquePolyBuffer(const UniquePolyBuffer& other)
    : Super(other), comparator(this), hasher(this), keys(10, hasher, comparator)
  {
    std::copy(other.keys.begin(), other.keys.end(), std::inserter(keys, keys.begin()));
  }

  UniquePolyBuffer(UniquePolyBuffer&& other)
    : Super(std::move(other)),
      comparator(std::move(other.comparator)),
      hasher(std::move(other.hasher)),
      keys(std::move(other.keys))
  {}

  UniquePolyBuffer& operator=(const UniquePolyBuffer& other) {
    Super::operator=(other);
    std::copy(other.keys.begin(), other.keys.end(), std::inserter(keys, keys.begin()));
    return *this;
  }

  UniquePolyBuffer& operator=(UniquePolyBuffer&& other) {
    comparator = std::move(other.comparator);
    hasher = std::move(other.hasher);
    keys = std::move(other.keys);
    Super::operator=(std::move(other));
    return *this;
  }

  ~UniquePolyBuffer() {}

  void rebuildKeys() {
    size_t foffset = 0, sz = Super::size(unit_t{});
    for (size_t i = 0; i < sz; ++i) {
      Tag tg = Super::tag_at(i);
      keys.insert(std::make_pair(tg, std::move(UPBValueProxy { foffset })));
      foffset += this->elemsize(tg);
    }
  }

  //////////////////////////////////
  //
  // Tag-specific accessors.

  template<typename T>
  unit_t append(Tag tg, const T& t) {
    UPBValueProxy probe { reinterpret_cast<char*>(const_cast<T*>(&t)) };
    if ( keys.find(std::make_pair(tg, probe)) == keys.end() ) {
      FContainer* ncf = const_cast<FContainer*>(Super::fixedc());
      size_t offset = buffer_size(ncf);
      Super::append(tg, t);
      keys.insert(std::make_pair(tg, std::move(UPBValueProxy { offset })));
    }
    return unit_t{};
  }

  // Clears a container, deleting any backing buffer.
  unit_t clear(unit_t) {
    keys.clear();
    return Super::clear(unit_t{});
  }

  unit_t load(const base_string& str) {
    return load(base_string(str));
  }

  // Restores a flat poly buffer from a string.
  unit_t load(base_string&& str) {
    Super::load(std::forward<base_string>(str));
    rebuildKeys();
    return unit_t{};
  }

  template <class archive>
  void save(archive& a, const unsigned int) const {
    a << boost::serialization::base_object<const Super>(*this);
  }

  template <class archive>
  void load(archive& a, const unsigned int) {
    a >> boost::serialization::base_object<Super>(*this);
    rebuildKeys();
  }

  template <class archive>
  void serialize(archive& a) const {
    Super::serialize(a);
  }

  template <class archive>
  void serialize(archive& a) {
    Super::serialize(a);
    rebuildKeys();
  }

  BOOST_SERIALIZATION_SPLIT_MEMBER()

private:
  friend class UPBEqual<Ignore, Derived, Tag>;
  friend class UPBHash<Ignore, Derived, Tag>;
  UPBEqual<Ignore, Derived, Tag> comparator;
  UPBHash<Ignore, Derived, Tag> hasher;
  std::unordered_set<UPBKey<Tag>, UPBHash<Ignore, Derived, Tag>, UPBEqual<Ignore, Derived, Tag>> keys;
};

}; // end namespace Libdynamic

template<class Ignored, class Derived>
using UniquePolyBuffer = Libdynamic::UniquePolyBuffer<Ignored, Derived>;

}; // end namespace K3

namespace YAML {
template <class E, class Derived>
struct convert<K3::UniquePolyBuffer<E, Derived>> {
  using Tag = typename K3::UniquePolyBuffer<E, Derived>::Tag;
  static Node encode(const K3::UniquePolyBuffer<E, Derived>& c) {
    Node node;
    bool flag = true;
    c.iterate([&c, &node, &flag](Tag tg, size_t idx, size_t offset){
      if (flag) { flag = false; }
      node.push_back(c.yamlencode(tg, idx, offset));
    });
    if (flag) {
      node = YAML::Load("[]");
    }
    return node;
  }

  static bool decode(const Node& node, K3::UniquePolyBuffer<E, Derived>& c) {
    for (auto i : node) {
      c.yamldecode(i);
    }
    return true;
  }
};
}  // namespace YAML

namespace JSON {
using namespace rapidjson;
template <class E, class Derived>
struct convert<K3::UniquePolyBuffer<E, Derived>> {
  using Tag = typename K3::UniquePolyBuffer<E, Derived>::Tag;
  template <class Allocator>
  static Value encode(const K3::UniquePolyBuffer<E, Derived>& c, Allocator& al) {
    Value v;
    v.SetObject();
    v.AddMember("type", Value("UniquePolyBuffer"), al);
    Value inner;
    inner.SetArray();
    c.iterate([&c, &inner, &al](Tag tg, size_t idx, size_t offset){
      inner.PushBack(c.jsonencode(tg, idx, offset, al), al);
    });
    v.AddMember("value", inner.Move(), al);
    return v;
  }
};
}  // namespace JSON

#endif // HAS_LIBDYNAMIC

#endif
<commit_msg>Clearing UPB keys prior to copy assignment<commit_after>#ifndef K3_UNIQPOLYBUF
#define K3_UNIQPOLYBUF

#include <unordered_set>

#if HAS_LIBDYNAMIC

#include <boost/serialization/array.hpp>
#include <boost/serialization/string.hpp>
#include <boost/functional/hash.hpp>

#include <yaml-cpp/yaml.h>
#include <rapidjson/document.h>
#include <csvpp/csv.h>
#include "serialization/Json.hpp"

#include "Common.hpp"
#include "collections/STLDataspace.hpp"
#include "collections/Collection.hpp"
#include "collections/FlatPolyBuffer.hpp"

namespace K3 {
namespace Libdynamic {

template<typename Ignore, typename Derived>
class UniquePolyBuffer;

//////////////////////////////////////////
//
// Buffer functors.

struct UPBValueProxy {
  UPBValueProxy(size_t o) : asOffset(true), offset(o) {}
  UPBValueProxy(char* p) : asOffset(false), elem(p) {}

  bool asOffset;
  union {
    char* elem;
    size_t offset;
  };
};

template<typename Tag>
using UPBKey = std::pair<Tag, UPBValueProxy>;

template<class Ignore, class T, typename Tag>
struct UPBEqual : std::binary_function<UPBKey<Tag>, UPBKey<Tag>, bool>
{
  using Container = typename FlatPolyBuffer<Ignore, T>::Container;
  using UPB = UniquePolyBuffer<Ignore, T>;
  using ExternalizerT = BufferExternalizer;
  using InternalizerT = BufferInternalizer;

  Container* container;
  ExternalizerT etl;
  InternalizerT itl;

  UPBEqual(UPB* c)
    : container(c->container.get()),
      etl(container->variable(), ExternalizerT::ExternalizeOp::Reuse),
      itl(container->variable())
  {}

  bool operator()(const UPBKey<Tag>& left, const UPBKey<Tag>& right) const {
    auto buffer = container->fixed();
    char* lp = left.second.asOffset? buffer_data(buffer) + left.second.offset : left.second.elem;
    char* rp = right.second.asOffset? buffer_data(buffer) + right.second.offset : right.second.elem;

    if ( !container->internalized ) {
      if ( left.second.asOffset ) { T::internalize(const_cast<InternalizerT&>(itl), left.first, lp); }
      if ( right.second.asOffset ) { T::internalize(const_cast<InternalizerT&>(itl), right.first, rp); }
    }

    bool r = T::equalelem(left.first, lp, right.first, rp);

    if ( !container->internalized ) {
      if ( left.second.asOffset ) { T::externalize(const_cast<ExternalizerT&>(etl), left.first, lp); }
      if ( right.second.asOffset ) { T::externalize(const_cast<ExternalizerT&>(etl), right.first, rp); }
    }
    return r;
  }
};

template<typename Ignore, typename T, typename Tag>
struct UPBHash : std::unary_function<UPBKey<Tag>, std::size_t>
{
  using Container = typename FlatPolyBuffer<Ignore, T>::Container;
  using UPB = UniquePolyBuffer<Ignore, T>;
  using ExternalizerT = BufferExternalizer;
  using InternalizerT = BufferInternalizer;

  Container* container;
  ExternalizerT etl;
  InternalizerT itl;

  UPBHash(UPB* c)
    : container(c->container.get()),
      etl(container->variable(), ExternalizerT::ExternalizeOp::Reuse),
      itl(container->variable())
  {}

  std::size_t operator()(const UPBKey<Tag>& k) const {
    std::hash<Tag> hash;
    size_t h1 = hash(k.first);
    auto buffer = container->fixed();
    char* p = k.second.asOffset? buffer_data(buffer) + k.second.offset : k.second.elem;
    if ( !container->internalized && k.second.asOffset ) {
      T::internalize(const_cast<InternalizerT&>(itl), k.first, p);
    }

    boost::hash_combine(h1, T::hashelem(k.first, p));

    if ( !container->internalized && k.second.asOffset ) {
      T::externalize(const_cast<ExternalizerT&>(etl), k.first, p);
    }
    return h1;
  }
};

//////////////////////////////////////////
//
// UniquePolyBuffer

template<class Ignore, class Derived>
class UniquePolyBuffer : public FlatPolyBuffer<Ignore, Derived> {
public:
  using Super = FlatPolyBuffer<Ignore, Derived>;
  using Tag = typename Super::Tag;

  using FContainer = typename Super::FContainer;
  using VContainer = typename Super::VContainer;
  using TContainer = typename Super::TContainer;

  UniquePolyBuffer()
    : Super(), comparator(this), hasher(this), keys(10, hasher, comparator)
  {}

  UniquePolyBuffer(const UniquePolyBuffer& other)
    : Super(other), comparator(this), hasher(this), keys(10, hasher, comparator)
  {
    std::copy(other.keys.begin(), other.keys.end(), std::inserter(keys, keys.begin()));
  }

  UniquePolyBuffer(UniquePolyBuffer&& other)
    : Super(std::move(other)),
      comparator(std::move(other.comparator)),
      hasher(std::move(other.hasher)),
      keys(std::move(other.keys))
  {}

  UniquePolyBuffer& operator=(const UniquePolyBuffer& other) {
    Super::operator=(other);
    keys.clear();
    std::copy(other.keys.begin(), other.keys.end(), std::inserter(keys, keys.begin()));
    return *this;
  }

  UniquePolyBuffer& operator=(UniquePolyBuffer&& other) {
    comparator = std::move(other.comparator);
    hasher = std::move(other.hasher);
    keys = std::move(other.keys);
    Super::operator=(std::move(other));
    return *this;
  }

  ~UniquePolyBuffer() {}

  void rebuildKeys() {
    size_t foffset = 0, sz = Super::size(unit_t{});
    for (size_t i = 0; i < sz; ++i) {
      Tag tg = Super::tag_at(i);
      keys.insert(std::make_pair(tg, std::move(UPBValueProxy { foffset })));
      foffset += this->elemsize(tg);
    }
  }

  //////////////////////////////////
  //
  // Tag-specific accessors.

  template<typename T>
  unit_t append(Tag tg, const T& t) {
    UPBValueProxy probe { reinterpret_cast<char*>(const_cast<T*>(&t)) };
    if ( keys.find(std::make_pair(tg, probe)) == keys.end() ) {
      FContainer* ncf = const_cast<FContainer*>(Super::fixedc());
      size_t offset = buffer_size(ncf);
      Super::append(tg, t);
      keys.insert(std::make_pair(tg, std::move(UPBValueProxy { offset })));
    }
    return unit_t{};
  }

  // Clears a container, deleting any backing buffer.
  unit_t clear(unit_t) {
    keys.clear();
    return Super::clear(unit_t{});
  }

  unit_t load(const base_string& str) {
    return load(base_string(str));
  }

  // Restores a flat poly buffer from a string.
  unit_t load(base_string&& str) {
    Super::load(std::forward<base_string>(str));
    rebuildKeys();
    return unit_t{};
  }

  template <class archive>
  void save(archive& a, const unsigned int) const {
    a << boost::serialization::base_object<const Super>(*this);
  }

  template <class archive>
  void load(archive& a, const unsigned int) {
    a >> boost::serialization::base_object<Super>(*this);
    rebuildKeys();
  }

  template <class archive>
  void serialize(archive& a) const {
    Super::serialize(a);
  }

  template <class archive>
  void serialize(archive& a) {
    Super::serialize(a);
    rebuildKeys();
  }

  BOOST_SERIALIZATION_SPLIT_MEMBER()

private:
  friend class UPBEqual<Ignore, Derived, Tag>;
  friend class UPBHash<Ignore, Derived, Tag>;
  UPBEqual<Ignore, Derived, Tag> comparator;
  UPBHash<Ignore, Derived, Tag> hasher;
  std::unordered_set<UPBKey<Tag>, UPBHash<Ignore, Derived, Tag>, UPBEqual<Ignore, Derived, Tag>> keys;
};

}; // end namespace Libdynamic

template<class Ignored, class Derived>
using UniquePolyBuffer = Libdynamic::UniquePolyBuffer<Ignored, Derived>;

}; // end namespace K3

namespace YAML {
template <class E, class Derived>
struct convert<K3::UniquePolyBuffer<E, Derived>> {
  using Tag = typename K3::UniquePolyBuffer<E, Derived>::Tag;
  static Node encode(const K3::UniquePolyBuffer<E, Derived>& c) {
    Node node;
    bool flag = true;
    c.iterate([&c, &node, &flag](Tag tg, size_t idx, size_t offset){
      if (flag) { flag = false; }
      node.push_back(c.yamlencode(tg, idx, offset));
    });
    if (flag) {
      node = YAML::Load("[]");
    }
    return node;
  }

  static bool decode(const Node& node, K3::UniquePolyBuffer<E, Derived>& c) {
    for (auto i : node) {
      c.yamldecode(i);
    }
    return true;
  }
};
}  // namespace YAML

namespace JSON {
using namespace rapidjson;
template <class E, class Derived>
struct convert<K3::UniquePolyBuffer<E, Derived>> {
  using Tag = typename K3::UniquePolyBuffer<E, Derived>::Tag;
  template <class Allocator>
  static Value encode(const K3::UniquePolyBuffer<E, Derived>& c, Allocator& al) {
    Value v;
    v.SetObject();
    v.AddMember("type", Value("UniquePolyBuffer"), al);
    Value inner;
    inner.SetArray();
    c.iterate([&c, &inner, &al](Tag tg, size_t idx, size_t offset){
      inner.PushBack(c.jsonencode(tg, idx, offset, al), al);
    });
    v.AddMember("value", inner.Move(), al);
    return v;
  }
};
}  // namespace JSON

#endif // HAS_LIBDYNAMIC

#endif
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <cstring>
#include <string>
#include <vector>
#include <iomanip>
#include <cmath>
#include <list>
#include <bitset>

using namespace std;

#define ll long long
#define lson l,mid,id<<1
#define rson mid+1,r,id<<1|1

typedef pair<int, int>pii;
typedef pair<ll, ll>pll;
typedef pair<double, double>pdd;

const double eps = 1e-6;
const ll  LINF = 0x3f3f3f3f3f3f3f3fLL;
const int INF = 0x3f3f3f3f;
const double FINF = 1e18;

#define x first
#define y second

#define REP(i,j,k) for(int i =(j);i<=(k);i++)
#define REPD(i,j,k) for(int i =(j);i>=(k);i--)
#define print(x) cout<<(x)<<endl;
#define IOS ios::sync_with_stdio(0);cin.tie(0);

char a,b;

void Init(){
	cin>>b;

	return ;
}

void Solve(){
	int lena;
	lena =strlen(a);

	REP(i,0,lena-1){
		a[lena+i]=a[i];
	}
	a[lena*2]=0;

	cout<<search(a,a+2*lena,b,b+strlen(b))<<endl;

	return ;
}

int main(){
#ifdef LOCAL
	freopen("hdu2203.in","r",stdin);
#endif

	while(cin>>a)
	Init(),Solve();
	return 0;
}<commit_msg>update hdu2203<commit_after>#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <cstring>
#include <string>
#include <vector>
#include <iomanip>
#include <cmath>
#include <list>
#include <bitset>

using namespace std;

#define ll long long
#define lson l,mid,id<<1
#define rson mid+1,r,id<<1|1

typedef pair<int, int>pii;
typedef pair<ll, ll>pll;
typedef pair<double, double>pdd;

const double eps = 1e-6;
const ll  LINF = 0x3f3f3f3f3f3f3f3fLL;
const int INF = 0x3f3f3f3f;
const double FINF = 1e18;

#define x first
#define y second

#define REP(i,j,k) for(int i =(j);i<=(k);i++)
#define REPD(i,j,k) for(int i =(j);i>=(k);i--)
#define print(x) cout<<(x)<<endl;
#define IOS ios::sync_with_stdio(0);cin.tie(0);

char a[300005],b[100005];

void Init(){
	cin>>b;

	return ;
}

void Solve(){
	int lena;
	lena =strlen(a);

	REP(i,0,lena-1){
		a[lena+i]=a[i];
	}
	a[lena*2]=0;

	cout<<search(a,a+2*lena,b,b+strlen(b))<<endl;

	return ;
}

int main(){
#ifdef LOCAL
	freopen("hdu2203.in","r",stdin);
#endif

	while(cin>>a)
	Init(),Solve();
	return 0;
}<|endoftext|>


<commit_before>#include "my_application.h"

int main(int argc, char** argv) {
  g_autoptr(MyApplication) app = my_application_new();
  return g_application_run(G_APPLICATION(app), argc, argv);
}
<commit_msg>ensure taqo runs on x11 backend<commit_after>#include "my_application.h"

int main(int argc, char** argv) {
  // Only X11 is currently supported.
  // Wayland support is being developed: https://github.com/flutter/flutter/issues/57932.
  gdk_set_allowed_backends("x11");

  g_autoptr(MyApplication) app = my_application_new();
  return g_application_run(G_APPLICATION(app), argc, argv);
}
<|endoftext|>


<commit_before>#include "hid.h"
#include "base/debug.h"
#include <stdio.h>
#include <strsafe.h>
#include <tchar.h>
#include <wchar.h>
#include <Hidsdi.h>
#include <g3log/g3log.hpp>
#include <g3log/logworker.hpp>

#define KEY_LENGTH 255

static unsigned short device_id[][2] = {
  {0x046D, 0xC29B} /* Logitech G27 */
};

static unsigned short keys[KEY_LENGTH] = {0};
static unsigned short keys_index = 0;

void hid_poll(LPARAM lParam)
{
  unsigned int buffer_size;

  GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &buffer_size,
                  sizeof(RAWINPUTHEADER));

  RAWINPUT *buffer = (RAWINPUT*)malloc(buffer_size);

  GetRawInputData((HRAWINPUT)lParam, RID_INPUT, buffer, &buffer_size,
                  sizeof(RAWINPUTHEADER));

  GetRawInputDeviceInfo(buffer->header.hDevice, RIDI_PREPARSEDDATA,
                        NULL, &buffer_size);

  PHIDP_PREPARSED_DATA preparsed_data = (PHIDP_PREPARSED_DATA)malloc(buffer_size);
  GetRawInputDeviceInfo(buffer->header.hDevice, RIDI_PREPARSEDDATA,
                        preparsed_data, &buffer_size);

  PHIDP_CAPS caps = (PHIDP_CAPS)malloc(sizeof(HIDP_CAPS));

  HidP_GetCaps(preparsed_data, caps);

  GUID device_guid;
  HidD_GetHidGuid(&device_guid);

  wchar_t product_string[sizeof(wchar_t) * 128] = {0};
  wchar_t manufacturer_string[sizeof(wchar_t) * 128] = {0};
  wchar_t serial_number[sizeof(wchar_t) * 128] = {0};

  GetRawInputDeviceInfo(buffer->header.hDevice, RIDI_DEVICENAME,
                        NULL, &buffer_size);

  wchar_t *name = (wchar_t*)malloc(sizeof(wchar_t) * (buffer_size+1));

  GetRawInputDeviceInfo(buffer->header.hDevice, RIDI_DEVICENAME,
                        name, &buffer_size);

  HANDLE hid = CreateFile(name, GENERIC_READ | GENERIC_WRITE,
                          FILE_SHARE_READ | FILE_SHARE_WRITE,
                          NULL, OPEN_EXISTING, NULL, NULL);
  BOOL h = true;

  if (hid != INVALID_HANDLE_VALUE) {
    h = HidD_GetProductString(hid, product_string, sizeof(wchar_t)*128);
    h = HidD_GetManufacturerString(hid, manufacturer_string, sizeof(wchar_t)*128);
    h = HidD_GetSerialNumberString(hid, serial_number, sizeof(wchar_t)*128);
  }

  unsigned short caps_length = caps->NumberInputButtonCaps;

  PHIDP_BUTTON_CAPS button_caps =
      (PHIDP_BUTTON_CAPS)malloc(sizeof(HIDP_BUTTON_CAPS) * caps->NumberInputButtonCaps);

  HidP_GetButtonCaps(HidP_Input, button_caps, &caps_length, preparsed_data);

  unsigned char num_buttons =
      button_caps->Range.UsageMax - button_caps->Range.UsageMin + 1;

  PHIDP_VALUE_CAPS value_caps =
      (PHIDP_VALUE_CAPS)malloc(sizeof(HIDP_VALUE_CAPS) * caps->NumberInputValueCaps);

  caps_length = caps->NumberInputValueCaps;
  HidP_GetValueCaps(HidP_Input, value_caps, &caps_length, preparsed_data);

  unsigned long usage_length = num_buttons;
  PUSAGE usage = (PUSAGE)malloc(sizeof(USAGE) * usage_length);
  long ret;
  ret = HidP_GetUsages(HidP_Input, button_caps->UsagePage, 0, usage, &usage_length,
                       preparsed_data, (PCHAR)buffer->data.hid.bRawData,
                       buffer->data.hid.dwSizeHid);

  /* This can be improved drastically, iterate over keys first then usage */
  for (int i = 0; i < usage_length; i++) {

    bool present = false;
    for (int x = 0; x <= keys_index; x++) {

      if (keys[x] == usage[i]) {
        present = true;
        break;
      }

    }

    /* If not in key array */
    if (!present) {
      keys[keys_index] = usage[i];
      LOGF(DEBUG, "Button %d pressed (%S %S)",
           usage[i],
           (manufacturer_string[0] == '\0') ? L"*": manufacturer_string,
           (product_string[0] == '\0') ? L"*": product_string);
      keys_index++;
    }
  }

  /* Some key(s) was released */
  /* This block is assuming the smallest button value is 1 */
  if (keys_index > usage_length) {
    for (int i = 0; i <= KEY_LENGTH; i++) {
      bool present = false;

      for (int x = 0; x <= usage_length; x++) {
        if (keys[i] == usage[x]) {
          present = true;
          break;
        }
      }
      if (!present) {
        LOGF(DEBUG, "Button %d pressed (%S %S)",
           keys[i],
           (manufacturer_string[0] == '\0') ? L"*": manufacturer_string,
           (product_string[0] == '\0') ? L"*": product_string);
        keys[i] = 0;
        keys_index--;
      }
    }
  }

  unsigned long usage_value;
  for (int i = 0; i < caps->NumberInputValueCaps; i++) {

    HidP_GetUsageValue(HidP_Input, value_caps[i].UsagePage, 0,
                       value_caps[i].Range.UsageMin, &usage_value,
                       preparsed_data, (PCHAR)buffer->data.hid.bRawData,
                       buffer->data.hid.dwSizeHid);
    ret++;
  }

  free(buffer);
  free(preparsed_data);
  free(button_caps);
  free(usage);

}

void enumerate_devices()
{
  /* Check if there are recgonized devices plugged in */
  unsigned int num_devices = 0;
  LOGF(DEBUG, "Enumerating system HID devices (manufacturer product vId pId)");
  GetRawInputDeviceList(NULL, &num_devices, sizeof(RAWINPUTDEVICELIST));

  if (num_devices <= 0) {
    DEXIT_PROCESS(L"Failed to enumerate system devices", 0);
  }

  RAWINPUTDEVICELIST *devices =
      (RAWINPUTDEVICELIST*)malloc(num_devices * sizeof(RAWINPUTDEVICELIST));

  if (!GetRawInputDeviceList(devices, &num_devices, sizeof(RAWINPUTDEVICELIST))) {
    DEXIT_PROCESS(L"Failed to enumerate system devices", GetLastError());
  }

  for (int i = 0; i < num_devices; i++) {
    unsigned int size = 0;
    int ret = 0;

    ret = GetRawInputDeviceInfo(devices[i].hDevice, RIDI_DEVICENAME, NULL, &size);

    wchar_t *name = (wchar_t*)malloc(sizeof(wchar_t) * (size+1));

    ret = GetRawInputDeviceInfo(devices[i].hDevice, RIDI_DEVICENAME, name, &size);

    ret = GetRawInputDeviceInfo(devices[i].hDevice, RIDI_DEVICEINFO, NULL, &size);

    PRID_DEVICE_INFO device_info =
        (PRID_DEVICE_INFO)malloc(size);

    ret = GetRawInputDeviceInfo(devices[i].hDevice, RIDI_DEVICEINFO, device_info, &size);

    HANDLE hid_handle = CreateFile(name, GENERIC_READ | GENERIC_WRITE,
                                   FILE_SHARE_READ | FILE_SHARE_WRITE,
                                   NULL, OPEN_ALWAYS,
                                   FILE_FLAG_OVERLAPPED, NULL);

    wchar_t product_string[sizeof(wchar_t) * 128] = {0};
    wchar_t manufacturer_string[sizeof(wchar_t) * 128] = {0};
    wchar_t serial_number[sizeof(wchar_t) * 128] = {0};

    if (hid_handle != INVALID_HANDLE_VALUE) {
      ret = HidD_GetManufacturerString(hid_handle, manufacturer_string, sizeof(wchar_t) * 128);
      ret = HidD_GetProductString(hid_handle, product_string, sizeof(wchar_t) * 128);
      ret = HidD_GetSerialNumberString(hid_handle, serial_number, sizeof(wchar_t) * 128);

      LOGF(INFO, "device %S %S %04x %04x",
           (manufacturer_string[0] == '\0') ? L"*": manufacturer_string,
           (product_string[0] == '\0') ? L"*": product_string,
           device_info->hid.dwVendorId,
           device_info->hid.dwProductId);

      CloseHandle(hid_handle);
    }

    free(device_info);
    free(name);
  }

  free(devices);
}

void register_devices(HWND hWnd)
{
  char debug[256];
  wchar_t debug_wide[256];

  RAWINPUTDEVICE wheel_input;

  LOGF(DEBUG, "This is a debug log from hid module");

  wheel_input.usUsagePage = 1;
  wheel_input.usUsage = 4;
  wheel_input.dwFlags = RIDEV_INPUTSINK;
  wheel_input.hwndTarget = hWnd;

  if (!RegisterRawInputDevices(&wheel_input, 1, sizeof(RAWINPUTDEVICE))) {
    LOGF(FATAL, "failed to register HID devices");
    DEXIT_PROCESS(L"Failed to register HID devices", GetLastError());
  }

}
<commit_msg>Fix string typo<commit_after>#include "hid.h"
#include "base/debug.h"
#include <stdio.h>
#include <strsafe.h>
#include <tchar.h>
#include <wchar.h>
#include <Hidsdi.h>
#include <g3log/g3log.hpp>
#include <g3log/logworker.hpp>

#define KEY_LENGTH 255

static unsigned short device_id[][2] = {
  {0x046D, 0xC29B} /* Logitech G27 */
};

static unsigned short keys[KEY_LENGTH] = {0};
static unsigned short keys_index = 0;

void hid_poll(LPARAM lParam)
{
  unsigned int buffer_size;

  GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &buffer_size,
                  sizeof(RAWINPUTHEADER));

  RAWINPUT *buffer = (RAWINPUT*)malloc(buffer_size);

  GetRawInputData((HRAWINPUT)lParam, RID_INPUT, buffer, &buffer_size,
                  sizeof(RAWINPUTHEADER));

  GetRawInputDeviceInfo(buffer->header.hDevice, RIDI_PREPARSEDDATA,
                        NULL, &buffer_size);

  PHIDP_PREPARSED_DATA preparsed_data = (PHIDP_PREPARSED_DATA)malloc(buffer_size);
  GetRawInputDeviceInfo(buffer->header.hDevice, RIDI_PREPARSEDDATA,
                        preparsed_data, &buffer_size);

  PHIDP_CAPS caps = (PHIDP_CAPS)malloc(sizeof(HIDP_CAPS));

  HidP_GetCaps(preparsed_data, caps);

  GUID device_guid;
  HidD_GetHidGuid(&device_guid);

  wchar_t product_string[sizeof(wchar_t) * 128] = {0};
  wchar_t manufacturer_string[sizeof(wchar_t) * 128] = {0};
  wchar_t serial_number[sizeof(wchar_t) * 128] = {0};

  GetRawInputDeviceInfo(buffer->header.hDevice, RIDI_DEVICENAME,
                        NULL, &buffer_size);

  wchar_t *name = (wchar_t*)malloc(sizeof(wchar_t) * (buffer_size+1));

  GetRawInputDeviceInfo(buffer->header.hDevice, RIDI_DEVICENAME,
                        name, &buffer_size);

  HANDLE hid = CreateFile(name, GENERIC_READ | GENERIC_WRITE,
                          FILE_SHARE_READ | FILE_SHARE_WRITE,
                          NULL, OPEN_EXISTING, NULL, NULL);
  BOOL h = true;

  if (hid != INVALID_HANDLE_VALUE) {
    h = HidD_GetProductString(hid, product_string, sizeof(wchar_t)*128);
    h = HidD_GetManufacturerString(hid, manufacturer_string, sizeof(wchar_t)*128);
    h = HidD_GetSerialNumberString(hid, serial_number, sizeof(wchar_t)*128);
  }

  unsigned short caps_length = caps->NumberInputButtonCaps;

  PHIDP_BUTTON_CAPS button_caps =
      (PHIDP_BUTTON_CAPS)malloc(sizeof(HIDP_BUTTON_CAPS) * caps->NumberInputButtonCaps);

  HidP_GetButtonCaps(HidP_Input, button_caps, &caps_length, preparsed_data);

  unsigned char num_buttons =
      button_caps->Range.UsageMax - button_caps->Range.UsageMin + 1;

  PHIDP_VALUE_CAPS value_caps =
      (PHIDP_VALUE_CAPS)malloc(sizeof(HIDP_VALUE_CAPS) * caps->NumberInputValueCaps);

  caps_length = caps->NumberInputValueCaps;
  HidP_GetValueCaps(HidP_Input, value_caps, &caps_length, preparsed_data);

  unsigned long usage_length = num_buttons;
  PUSAGE usage = (PUSAGE)malloc(sizeof(USAGE) * usage_length);
  long ret;
  ret = HidP_GetUsages(HidP_Input, button_caps->UsagePage, 0, usage, &usage_length,
                       preparsed_data, (PCHAR)buffer->data.hid.bRawData,
                       buffer->data.hid.dwSizeHid);

  /* This can be improved drastically, iterate over keys first then usage */
  for (int i = 0; i < usage_length; i++) {

    bool present = false;
    for (int x = 0; x <= keys_index; x++) {

      if (keys[x] == usage[i]) {
        present = true;
        break;
      }

    }

    /* If not in key array */
    if (!present) {
      keys[keys_index] = usage[i];
      LOGF(DEBUG, "Button %d pressed (%S %S)",
           usage[i],
           (manufacturer_string[0] == '\0') ? L"*": manufacturer_string,
           (product_string[0] == '\0') ? L"*": product_string);
      keys_index++;
    }
  }

  /* Some key(s) was released */
  /* This block is assuming the smallest button value is 1 */
  if (keys_index > usage_length) {
    for (int i = 0; i <= KEY_LENGTH; i++) {
      bool present = false;

      for (int x = 0; x <= usage_length; x++) {
        if (keys[i] == usage[x]) {
          present = true;
          break;
        }
      }
      if (!present) {
        LOGF(DEBUG, "Button %d released (%S %S)",
           keys[i],
           (manufacturer_string[0] == '\0') ? L"*": manufacturer_string,
           (product_string[0] == '\0') ? L"*": product_string);
        keys[i] = 0;
        keys_index--;
      }
    }
  }

  unsigned long usage_value;
  for (int i = 0; i < caps->NumberInputValueCaps; i++) {

    HidP_GetUsageValue(HidP_Input, value_caps[i].UsagePage, 0,
                       value_caps[i].Range.UsageMin, &usage_value,
                       preparsed_data, (PCHAR)buffer->data.hid.bRawData,
                       buffer->data.hid.dwSizeHid);
    ret++;
  }

  free(buffer);
  free(preparsed_data);
  free(button_caps);
  free(usage);

}

void enumerate_devices()
{
  /* Check if there are recgonized devices plugged in */
  unsigned int num_devices = 0;
  LOGF(DEBUG, "Enumerating system HID devices (manufacturer product vId pId)");
  GetRawInputDeviceList(NULL, &num_devices, sizeof(RAWINPUTDEVICELIST));

  if (num_devices <= 0) {
    DEXIT_PROCESS(L"Failed to enumerate system devices", 0);
  }

  RAWINPUTDEVICELIST *devices =
      (RAWINPUTDEVICELIST*)malloc(num_devices * sizeof(RAWINPUTDEVICELIST));

  if (!GetRawInputDeviceList(devices, &num_devices, sizeof(RAWINPUTDEVICELIST))) {
    DEXIT_PROCESS(L"Failed to enumerate system devices", GetLastError());
  }

  for (int i = 0; i < num_devices; i++) {
    unsigned int size = 0;
    int ret = 0;

    ret = GetRawInputDeviceInfo(devices[i].hDevice, RIDI_DEVICENAME, NULL, &size);

    wchar_t *name = (wchar_t*)malloc(sizeof(wchar_t) * (size+1));

    ret = GetRawInputDeviceInfo(devices[i].hDevice, RIDI_DEVICENAME, name, &size);

    ret = GetRawInputDeviceInfo(devices[i].hDevice, RIDI_DEVICEINFO, NULL, &size);

    PRID_DEVICE_INFO device_info =
        (PRID_DEVICE_INFO)malloc(size);

    ret = GetRawInputDeviceInfo(devices[i].hDevice, RIDI_DEVICEINFO, device_info, &size);

    HANDLE hid_handle = CreateFile(name, GENERIC_READ | GENERIC_WRITE,
                                   FILE_SHARE_READ | FILE_SHARE_WRITE,
                                   NULL, OPEN_ALWAYS,
                                   FILE_FLAG_OVERLAPPED, NULL);

    wchar_t product_string[sizeof(wchar_t) * 128] = {0};
    wchar_t manufacturer_string[sizeof(wchar_t) * 128] = {0};
    wchar_t serial_number[sizeof(wchar_t) * 128] = {0};

    if (hid_handle != INVALID_HANDLE_VALUE) {
      ret = HidD_GetManufacturerString(hid_handle, manufacturer_string, sizeof(wchar_t) * 128);
      ret = HidD_GetProductString(hid_handle, product_string, sizeof(wchar_t) * 128);
      ret = HidD_GetSerialNumberString(hid_handle, serial_number, sizeof(wchar_t) * 128);

      LOGF(INFO, "device %S %S %04x %04x",
           (manufacturer_string[0] == '\0') ? L"*": manufacturer_string,
           (product_string[0] == '\0') ? L"*": product_string,
           device_info->hid.dwVendorId,
           device_info->hid.dwProductId);

      CloseHandle(hid_handle);
    }

    free(device_info);
    free(name);
  }

  free(devices);
}

void register_devices(HWND hWnd)
{
  char debug[256];
  wchar_t debug_wide[256];

  RAWINPUTDEVICE wheel_input;

  LOGF(DEBUG, "This is a debug log from hid module");

  wheel_input.usUsagePage = 1;
  wheel_input.usUsage = 4;
  wheel_input.dwFlags = RIDEV_INPUTSINK;
  wheel_input.hwndTarget = hWnd;

  if (!RegisterRawInputDevices(&wheel_input, 1, sizeof(RAWINPUTDEVICE))) {
    LOGF(FATAL, "failed to register HID devices");
    DEXIT_PROCESS(L"Failed to register HID devices", GetLastError());
  }

}
<|endoftext|>


<commit_before>#include <iostream>

class Moveable
{
	public:
		Moveable()
		{
			std::cout << "Default constructor" << std::endl;
		}

		Moveable(const Moveable& m)
		{
			std::cout << "Copy constructor" << std::endl;
		}

		Moveable(const Moveable&& m)
		{
			std::cout << "Move constructor" << std::endl;
		}

		~Moveable()
		{
			std::cout << "Destructor" << std::endl;
		}

		static Moveable Instance()
		{
			return Moveable();
		}
};

int main()
{
	Moveable m;
	Moveable c(m);
  Moveable m3(Moveable::Instance());
}
<commit_msg>Making progress<commit_after>#include <iostream>

class Moveable
{
	public:

		int m_iField;

		Moveable()
		{
			m_iField = 0;
			std::cout << "Default constructor" << std::endl;
		}

		Moveable(const Moveable& m)
		{
			m_iField = 1;
			std::cout << "Copy constructor" << std::endl;
		}

		Moveable(const Moveable&& m)
		{
			m_iField = 2;
			std::cout << "Move constructor" << std::endl;
		}

    Moveable& operator = (const Moveable& m)
		{
			m_iField = m.m_iField;
			std::cout << "normal assignement" << std::endl;
		}

    Moveable& operator = (const Moveable&& m)
		{
			m_iField = m.m_iField;
			std::cout << "rvalue assignement" << std::endl;
		}

		static Moveable Instance()
		{
			std::cout << "Instance function" << std::endl;
			return Moveable();
		}
};

int main()
{
	Moveable m;
	Moveable c(m);
  Moveable m3;
	m3 = c;
}
<|endoftext|>


<commit_before>//===-- ConstantFolding.cpp - Analyze constant folding possibilities ------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This family of functions determines the possibility of performing constant
// folding.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/MathExtras.h"
#include <cerrno>
#include <cmath>
using namespace llvm;

//===----------------------------------------------------------------------===//
//  Constant Folding ...
//

/// canConstantFoldCallTo - Return true if its even possible to fold a call to
/// the specified function.
bool
llvm::canConstantFoldCallTo(Function *F) {
  const std::string &Name = F->getName();

  switch (F->getIntrinsicID()) {
  case Intrinsic::isunordered_f32:
  case Intrinsic::isunordered_f64:
  case Intrinsic::sqrt_f32:
  case Intrinsic::sqrt_f64:
  case Intrinsic::bswap_i16:
  case Intrinsic::bswap_i32:
  case Intrinsic::bswap_i64:
  // FIXME: these should be constant folded as well
  //case Intrinsic::ctpop_i8:
  //case Intrinsic::ctpop_i16:
  //case Intrinsic::ctpop_i32:
  //case Intrinsic::ctpop_i64:
  //case Intrinsic::ctlz_i8:
  //case Intrinsic::ctlz_i16:
  //case Intrinsic::ctlz_i32:
  //case Intrinsic::ctlz_i64:
  //case Intrinsic::cttz_i8:
  //case Intrinsic::cttz_i16:
  //case Intrinsic::cttz_i32:
  //case Intrinsic::cttz_i64:
    return true;
  default: break;
  }

  switch (Name[0])
  {
    case 'a':
      return Name == "acos" || Name == "asin" || Name == "atan" ||
             Name == "atan2";
    case 'c':
      return Name == "ceil" || Name == "cos" || Name == "cosf" ||
             Name == "cosh";
    case 'e':
      return Name == "exp";
    case 'f':
      return Name == "fabs" || Name == "fmod" || Name == "floor";
    case 'l':
      return Name == "log" || Name == "log10";
    case 'p':
      return Name == "pow";
    case 's':
      return Name == "sin" || Name == "sinh" ||
             Name == "sqrt" || Name == "sqrtf";
    case 't':
      return Name == "tan" || Name == "tanh";
    default:
      return false;
  }
}

Constant *
llvm::ConstantFoldFP(double (*NativeFP)(double), double V, const Type *Ty) {
  errno = 0;
  V = NativeFP(V);
  if (errno == 0)
    return ConstantFP::get(Ty, V);
  return 0;
}

/// ConstantFoldCall - Attempt to constant fold a call to the specified function
/// with the specified arguments, returning null if unsuccessful.
Constant *
llvm::ConstantFoldCall(Function *F, const std::vector<Constant*> &Operands) {
  const std::string &Name = F->getName();
  const Type *Ty = F->getReturnType();

  if (Operands.size() == 1) {
    if (ConstantFP *Op = dyn_cast<ConstantFP>(Operands[0])) {
      double V = Op->getValue();
      switch (Name[0])
      {
        case 'a':
          if (Name == "acos")
            return ConstantFoldFP(acos, V, Ty);
          else if (Name == "asin")
            return ConstantFoldFP(asin, V, Ty);
          else if (Name == "atan")
            return ConstantFP::get(Ty, atan(V));
          break;
        case 'c':
          if (Name == "ceil")
            return ConstantFoldFP(ceil, V, Ty);
          else if (Name == "cos")
            return ConstantFP::get(Ty, cos(V));
          else if (Name == "cosh")
            return ConstantFP::get(Ty, cosh(V));
          break;
        case 'e':
          if (Name == "exp")
            return ConstantFP::get(Ty, exp(V));
          break;
        case 'f':
          if (Name == "fabs")
            return ConstantFP::get(Ty, fabs(V));
          else if (Name == "floor")
            return ConstantFoldFP(floor, V, Ty);
          break;
        case 'l':
          if (Name == "log" && V > 0)
            return ConstantFP::get(Ty, log(V));
          else if (Name == "log10" && V > 0)
            return ConstantFoldFP(log10, V, Ty);
          else if (Name == "llvm.sqrt.f32" || Name == "llvm.sqrt.f64") {
            if (V >= -0.0)
              return ConstantFP::get(Ty, sqrt(V));
            else // Undefined
              return ConstantFP::get(Ty, 0.0);
          }
          break;
        case 's':
          if (Name == "sin")
            return ConstantFP::get(Ty, sin(V));
          else if (Name == "sinh")
            return ConstantFP::get(Ty, sinh(V));
          else if (Name == "sqrt" && V >= 0)
            return ConstantFP::get(Ty, sqrt(V));
          else if (Name == "sqrtf" && V >= 0)
            return ConstantFP::get(Ty, sqrt((float)V));
          break;
        case 't':
          if (Name == "tan")
            return ConstantFP::get(Ty, tan(V));
          else if (Name == "tanh")
            return ConstantFP::get(Ty, tanh(V));
          break;
        default:
          break;
      }
    } else if (ConstantInt *Op = dyn_cast<ConstantInt>(Operands[0])) {
      uint64_t V = Op->getZExtValue();
      if (Name == "llvm.bswap.i16")
        return ConstantInt::get(Ty, ByteSwap_16(V));
      else if (Name == "llvm.bswap.i32")
        return ConstantInt::get(Ty, ByteSwap_32(V));
      else if (Name == "llvm.bswap.i64")
        return ConstantInt::get(Ty, ByteSwap_64(V));
    }
  } else if (Operands.size() == 2) {
    if (ConstantFP *Op1 = dyn_cast<ConstantFP>(Operands[0])) {
      double Op1V = Op1->getValue();
      if (ConstantFP *Op2 = dyn_cast<ConstantFP>(Operands[1])) {
        double Op2V = Op2->getValue();

        if (Name == "llvm.isunordered.f32" || Name == "llvm.isunordered.f64")
          return ConstantBool::get(IsNAN(Op1V) || IsNAN(Op2V));
        else
        if (Name == "pow") {
          errno = 0;
          double V = pow(Op1V, Op2V);
          if (errno == 0)
            return ConstantFP::get(Ty, V);
        } else if (Name == "fmod") {
          errno = 0;
          double V = fmod(Op1V, Op2V);
          if (errno == 0)
            return ConstantFP::get(Ty, V);
        } else if (Name == "atan2")
          return ConstantFP::get(Ty, atan2(Op1V,Op2V));
      }
    }
  }
  return 0;
}

<commit_msg>remove llvm.isunordered<commit_after>//===-- ConstantFolding.cpp - Analyze constant folding possibilities ------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This family of functions determines the possibility of performing constant
// folding.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/MathExtras.h"
#include <cerrno>
#include <cmath>
using namespace llvm;

//===----------------------------------------------------------------------===//
//  Constant Folding ...
//

/// canConstantFoldCallTo - Return true if its even possible to fold a call to
/// the specified function.
bool
llvm::canConstantFoldCallTo(Function *F) {
  const std::string &Name = F->getName();

  switch (F->getIntrinsicID()) {
  case Intrinsic::sqrt_f32:
  case Intrinsic::sqrt_f64:
  case Intrinsic::bswap_i16:
  case Intrinsic::bswap_i32:
  case Intrinsic::bswap_i64:
  // FIXME: these should be constant folded as well
  //case Intrinsic::ctpop_i8:
  //case Intrinsic::ctpop_i16:
  //case Intrinsic::ctpop_i32:
  //case Intrinsic::ctpop_i64:
  //case Intrinsic::ctlz_i8:
  //case Intrinsic::ctlz_i16:
  //case Intrinsic::ctlz_i32:
  //case Intrinsic::ctlz_i64:
  //case Intrinsic::cttz_i8:
  //case Intrinsic::cttz_i16:
  //case Intrinsic::cttz_i32:
  //case Intrinsic::cttz_i64:
    return true;
  default: break;
  }

  switch (Name[0])
  {
    case 'a':
      return Name == "acos" || Name == "asin" || Name == "atan" ||
             Name == "atan2";
    case 'c':
      return Name == "ceil" || Name == "cos" || Name == "cosf" ||
             Name == "cosh";
    case 'e':
      return Name == "exp";
    case 'f':
      return Name == "fabs" || Name == "fmod" || Name == "floor";
    case 'l':
      return Name == "log" || Name == "log10";
    case 'p':
      return Name == "pow";
    case 's':
      return Name == "sin" || Name == "sinh" ||
             Name == "sqrt" || Name == "sqrtf";
    case 't':
      return Name == "tan" || Name == "tanh";
    default:
      return false;
  }
}

Constant *
llvm::ConstantFoldFP(double (*NativeFP)(double), double V, const Type *Ty) {
  errno = 0;
  V = NativeFP(V);
  if (errno == 0)
    return ConstantFP::get(Ty, V);
  return 0;
}

/// ConstantFoldCall - Attempt to constant fold a call to the specified function
/// with the specified arguments, returning null if unsuccessful.
Constant *
llvm::ConstantFoldCall(Function *F, const std::vector<Constant*> &Operands) {
  const std::string &Name = F->getName();
  const Type *Ty = F->getReturnType();

  if (Operands.size() == 1) {
    if (ConstantFP *Op = dyn_cast<ConstantFP>(Operands[0])) {
      double V = Op->getValue();
      switch (Name[0])
      {
        case 'a':
          if (Name == "acos")
            return ConstantFoldFP(acos, V, Ty);
          else if (Name == "asin")
            return ConstantFoldFP(asin, V, Ty);
          else if (Name == "atan")
            return ConstantFP::get(Ty, atan(V));
          break;
        case 'c':
          if (Name == "ceil")
            return ConstantFoldFP(ceil, V, Ty);
          else if (Name == "cos")
            return ConstantFP::get(Ty, cos(V));
          else if (Name == "cosh")
            return ConstantFP::get(Ty, cosh(V));
          break;
        case 'e':
          if (Name == "exp")
            return ConstantFP::get(Ty, exp(V));
          break;
        case 'f':
          if (Name == "fabs")
            return ConstantFP::get(Ty, fabs(V));
          else if (Name == "floor")
            return ConstantFoldFP(floor, V, Ty);
          break;
        case 'l':
          if (Name == "log" && V > 0)
            return ConstantFP::get(Ty, log(V));
          else if (Name == "log10" && V > 0)
            return ConstantFoldFP(log10, V, Ty);
          else if (Name == "llvm.sqrt.f32" || Name == "llvm.sqrt.f64") {
            if (V >= -0.0)
              return ConstantFP::get(Ty, sqrt(V));
            else // Undefined
              return ConstantFP::get(Ty, 0.0);
          }
          break;
        case 's':
          if (Name == "sin")
            return ConstantFP::get(Ty, sin(V));
          else if (Name == "sinh")
            return ConstantFP::get(Ty, sinh(V));
          else if (Name == "sqrt" && V >= 0)
            return ConstantFP::get(Ty, sqrt(V));
          else if (Name == "sqrtf" && V >= 0)
            return ConstantFP::get(Ty, sqrt((float)V));
          break;
        case 't':
          if (Name == "tan")
            return ConstantFP::get(Ty, tan(V));
          else if (Name == "tanh")
            return ConstantFP::get(Ty, tanh(V));
          break;
        default:
          break;
      }
    } else if (ConstantInt *Op = dyn_cast<ConstantInt>(Operands[0])) {
      uint64_t V = Op->getZExtValue();
      if (Name == "llvm.bswap.i16")
        return ConstantInt::get(Ty, ByteSwap_16(V));
      else if (Name == "llvm.bswap.i32")
        return ConstantInt::get(Ty, ByteSwap_32(V));
      else if (Name == "llvm.bswap.i64")
        return ConstantInt::get(Ty, ByteSwap_64(V));
    }
  } else if (Operands.size() == 2) {
    if (ConstantFP *Op1 = dyn_cast<ConstantFP>(Operands[0])) {
      double Op1V = Op1->getValue();
      if (ConstantFP *Op2 = dyn_cast<ConstantFP>(Operands[1])) {
        double Op2V = Op2->getValue();

        if (Name == "pow") {
          errno = 0;
          double V = pow(Op1V, Op2V);
          if (errno == 0)
            return ConstantFP::get(Ty, V);
        } else if (Name == "fmod") {
          errno = 0;
          double V = fmod(Op1V, Op2V);
          if (errno == 0)
            return ConstantFP::get(Ty, V);
        } else if (Name == "atan2")
          return ConstantFP::get(Ty, atan2(Op1V,Op2V));
      }
    }
  }
  return 0;
}

<|endoftext|>


<commit_before>//===--- FrontendActions.cpp ----------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/Frontend/FrontendActions.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/Lex/Pragma.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/Parser.h"
#include "clang/Basic/FileManager.h"
#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/Utils.h"
#include "clang/Serialization/ASTWriter.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;

//===----------------------------------------------------------------------===//
// Custom Actions
//===----------------------------------------------------------------------===//

ASTConsumer *InitOnlyAction::CreateASTConsumer(CompilerInstance &CI,
                                               llvm::StringRef InFile) {
  return new ASTConsumer();
}

void InitOnlyAction::ExecuteAction() {
}

//===----------------------------------------------------------------------===//
// AST Consumer Actions
//===----------------------------------------------------------------------===//

ASTConsumer *ASTPrintAction::CreateASTConsumer(CompilerInstance &CI,
                                               llvm::StringRef InFile) {
  if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
    return CreateASTPrinter(OS);
  return 0;
}

ASTConsumer *ASTPrintXMLAction::CreateASTConsumer(CompilerInstance &CI,
                                                  llvm::StringRef InFile) {
  if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "xml"))
    return CreateASTPrinterXML(OS);
  return 0;
}

ASTConsumer *ASTDumpAction::CreateASTConsumer(CompilerInstance &CI,
                                              llvm::StringRef InFile) {
  return CreateASTDumper();
}

ASTConsumer *ASTDumpXMLAction::CreateASTConsumer(CompilerInstance &CI,
                                                 llvm::StringRef InFile) {
  llvm::raw_ostream *OS;
  if (CI.getFrontendOpts().OutputFile.empty())
    OS = &llvm::outs();
  else
    OS = CI.createDefaultOutputFile(false, InFile);
  if (!OS) return 0;
  return CreateASTDumperXML(*OS);
}

ASTConsumer *ASTViewAction::CreateASTConsumer(CompilerInstance &CI,
                                              llvm::StringRef InFile) {
  return CreateASTViewer();
}

ASTConsumer *DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI,
                                                       llvm::StringRef InFile) {
  return CreateDeclContextPrinter();
}

ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI,
                                                  llvm::StringRef InFile) {
  std::string Sysroot;
  llvm::raw_ostream *OS = 0;
  bool Chaining;
  if (ComputeASTConsumerArguments(CI, InFile, Sysroot, OS, Chaining))
    return 0;

  const char *isysroot = CI.getFrontendOpts().RelocatablePCH ?
                             Sysroot.c_str() : 0;
  return new PCHGenerator(CI.getPreprocessor(), Chaining, isysroot, OS);
}

bool GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI,
                                                    llvm::StringRef InFile,
                                                    std::string &Sysroot,
                                                    llvm::raw_ostream *&OS,
                                                    bool &Chaining) {
  Sysroot = CI.getHeaderSearchOpts().Sysroot;
  if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) {
    CI.getDiagnostics().Report(diag::err_relocatable_without_isysroot);
    return true;
  }

  OS = CI.createDefaultOutputFile(true, InFile);
  if (!OS)
    return true;

  Chaining = CI.getInvocation().getFrontendOpts().ChainedPCH &&
             !CI.getPreprocessorOpts().ImplicitPCHInclude.empty();
  return false;
}

ASTConsumer *InheritanceViewAction::CreateASTConsumer(CompilerInstance &CI,
                                                      llvm::StringRef InFile) {
  return CreateInheritanceViewer(CI.getFrontendOpts().ViewClassInheritance);
}

ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI,
                                                 llvm::StringRef InFile) {
  return new ASTConsumer();
}

//===----------------------------------------------------------------------===//
// Preprocessor Actions
//===----------------------------------------------------------------------===//

void DumpRawTokensAction::ExecuteAction() {
  Preprocessor &PP = getCompilerInstance().getPreprocessor();
  SourceManager &SM = PP.getSourceManager();

  // Start lexing the specified input file.
  const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
  Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOptions());
  RawLex.SetKeepWhitespaceMode(true);

  Token RawTok;
  RawLex.LexFromRawLexer(RawTok);
  while (RawTok.isNot(tok::eof)) {
    PP.DumpToken(RawTok, true);
    llvm::errs() << "\n";
    RawLex.LexFromRawLexer(RawTok);
  }
}

void DumpTokensAction::ExecuteAction() {
  Preprocessor &PP = getCompilerInstance().getPreprocessor();
  // Start preprocessing the specified input file.
  Token Tok;
  PP.EnterMainSourceFile();
  do {
    PP.Lex(Tok);
    PP.DumpToken(Tok, true);
    llvm::errs() << "\n";
  } while (Tok.isNot(tok::eof));
}

void GeneratePTHAction::ExecuteAction() {
  CompilerInstance &CI = getCompilerInstance();
  if (CI.getFrontendOpts().OutputFile.empty() ||
      CI.getFrontendOpts().OutputFile == "-") {
    // FIXME: Don't fail this way.
    // FIXME: Verify that we can actually seek in the given file.
    llvm::report_fatal_error("PTH requires a seekable file for output!");
  }
  llvm::raw_fd_ostream *OS =
    CI.createDefaultOutputFile(true, getCurrentFile());
  if (!OS) return;

  CacheTokens(CI.getPreprocessor(), OS);
}

void PreprocessOnlyAction::ExecuteAction() {
  Preprocessor &PP = getCompilerInstance().getPreprocessor();

  // Ignore unknown pragmas.
  PP.AddPragmaHandler(new EmptyPragmaHandler());

  Token Tok;
  // Start parsing the specified input file.
  PP.EnterMainSourceFile();
  do {
    PP.Lex(Tok);
  } while (Tok.isNot(tok::eof));
}

void PrintPreprocessedAction::ExecuteAction() {
  CompilerInstance &CI = getCompilerInstance();
  // Output file needs to be set to 'Binary', to avoid converting Unix style
  // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>).
  llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
  if (!OS) return;

  DoPrintPreprocessedInput(CI.getPreprocessor(), OS,
                           CI.getPreprocessorOutputOpts());
}

void PrintPreambleAction::ExecuteAction() {
  switch (getCurrentFileKind()) {
  case IK_C:
  case IK_CXX:
  case IK_ObjC:
  case IK_ObjCXX:
  case IK_OpenCL:
  case IK_CUDA:
    break;

  case IK_None:
  case IK_Asm:
  case IK_PreprocessedC:
  case IK_PreprocessedCXX:
  case IK_PreprocessedObjC:
  case IK_PreprocessedObjCXX:
  case IK_AST:
  case IK_LLVM_IR:
    // We can't do anything with these.
    return;
  }

  CompilerInstance &CI = getCompilerInstance();
  llvm::MemoryBuffer *Buffer
      = CI.getFileManager().getBufferForFile(getCurrentFile());
  if (Buffer) {
    unsigned Preamble = Lexer::ComputePreamble(Buffer).first;
    llvm::outs().write(Buffer->getBufferStart(), Preamble);
    delete Buffer;
  }
}
<commit_msg>libclang: Don't allow RemoveFileOnSignal to be called via libclang, badness can ensue.<commit_after>//===--- FrontendActions.cpp ----------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/Frontend/FrontendActions.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/Lex/Pragma.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/Parser.h"
#include "clang/Basic/FileManager.h"
#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/Utils.h"
#include "clang/Serialization/ASTWriter.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;

//===----------------------------------------------------------------------===//
// Custom Actions
//===----------------------------------------------------------------------===//

ASTConsumer *InitOnlyAction::CreateASTConsumer(CompilerInstance &CI,
                                               llvm::StringRef InFile) {
  return new ASTConsumer();
}

void InitOnlyAction::ExecuteAction() {
}

//===----------------------------------------------------------------------===//
// AST Consumer Actions
//===----------------------------------------------------------------------===//

ASTConsumer *ASTPrintAction::CreateASTConsumer(CompilerInstance &CI,
                                               llvm::StringRef InFile) {
  if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
    return CreateASTPrinter(OS);
  return 0;
}

ASTConsumer *ASTPrintXMLAction::CreateASTConsumer(CompilerInstance &CI,
                                                  llvm::StringRef InFile) {
  if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "xml"))
    return CreateASTPrinterXML(OS);
  return 0;
}

ASTConsumer *ASTDumpAction::CreateASTConsumer(CompilerInstance &CI,
                                              llvm::StringRef InFile) {
  return CreateASTDumper();
}

ASTConsumer *ASTDumpXMLAction::CreateASTConsumer(CompilerInstance &CI,
                                                 llvm::StringRef InFile) {
  llvm::raw_ostream *OS;
  if (CI.getFrontendOpts().OutputFile.empty())
    OS = &llvm::outs();
  else
    OS = CI.createDefaultOutputFile(false, InFile);
  if (!OS) return 0;
  return CreateASTDumperXML(*OS);
}

ASTConsumer *ASTViewAction::CreateASTConsumer(CompilerInstance &CI,
                                              llvm::StringRef InFile) {
  return CreateASTViewer();
}

ASTConsumer *DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI,
                                                       llvm::StringRef InFile) {
  return CreateDeclContextPrinter();
}

ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI,
                                                  llvm::StringRef InFile) {
  std::string Sysroot;
  llvm::raw_ostream *OS = 0;
  bool Chaining;
  if (ComputeASTConsumerArguments(CI, InFile, Sysroot, OS, Chaining))
    return 0;

  const char *isysroot = CI.getFrontendOpts().RelocatablePCH ?
                             Sysroot.c_str() : 0;
  return new PCHGenerator(CI.getPreprocessor(), Chaining, isysroot, OS);
}

bool GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI,
                                                    llvm::StringRef InFile,
                                                    std::string &Sysroot,
                                                    llvm::raw_ostream *&OS,
                                                    bool &Chaining) {
  Sysroot = CI.getHeaderSearchOpts().Sysroot;
  if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) {
    CI.getDiagnostics().Report(diag::err_relocatable_without_isysroot);
    return true;
  }

  // We use createOutputFile here because this is exposed via libclang, and we
  // must disable the RemoveFileOnSignal behavior.
  OS = CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
                           /*RemoveFileOnSignal=*/false, InFile);
  if (!OS)
    return true;

  Chaining = CI.getInvocation().getFrontendOpts().ChainedPCH &&
             !CI.getPreprocessorOpts().ImplicitPCHInclude.empty();
  return false;
}

ASTConsumer *InheritanceViewAction::CreateASTConsumer(CompilerInstance &CI,
                                                      llvm::StringRef InFile) {
  return CreateInheritanceViewer(CI.getFrontendOpts().ViewClassInheritance);
}

ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI,
                                                 llvm::StringRef InFile) {
  return new ASTConsumer();
}

//===----------------------------------------------------------------------===//
// Preprocessor Actions
//===----------------------------------------------------------------------===//

void DumpRawTokensAction::ExecuteAction() {
  Preprocessor &PP = getCompilerInstance().getPreprocessor();
  SourceManager &SM = PP.getSourceManager();

  // Start lexing the specified input file.
  const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
  Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOptions());
  RawLex.SetKeepWhitespaceMode(true);

  Token RawTok;
  RawLex.LexFromRawLexer(RawTok);
  while (RawTok.isNot(tok::eof)) {
    PP.DumpToken(RawTok, true);
    llvm::errs() << "\n";
    RawLex.LexFromRawLexer(RawTok);
  }
}

void DumpTokensAction::ExecuteAction() {
  Preprocessor &PP = getCompilerInstance().getPreprocessor();
  // Start preprocessing the specified input file.
  Token Tok;
  PP.EnterMainSourceFile();
  do {
    PP.Lex(Tok);
    PP.DumpToken(Tok, true);
    llvm::errs() << "\n";
  } while (Tok.isNot(tok::eof));
}

void GeneratePTHAction::ExecuteAction() {
  CompilerInstance &CI = getCompilerInstance();
  if (CI.getFrontendOpts().OutputFile.empty() ||
      CI.getFrontendOpts().OutputFile == "-") {
    // FIXME: Don't fail this way.
    // FIXME: Verify that we can actually seek in the given file.
    llvm::report_fatal_error("PTH requires a seekable file for output!");
  }
  llvm::raw_fd_ostream *OS =
    CI.createDefaultOutputFile(true, getCurrentFile());
  if (!OS) return;

  CacheTokens(CI.getPreprocessor(), OS);
}

void PreprocessOnlyAction::ExecuteAction() {
  Preprocessor &PP = getCompilerInstance().getPreprocessor();

  // Ignore unknown pragmas.
  PP.AddPragmaHandler(new EmptyPragmaHandler());

  Token Tok;
  // Start parsing the specified input file.
  PP.EnterMainSourceFile();
  do {
    PP.Lex(Tok);
  } while (Tok.isNot(tok::eof));
}

void PrintPreprocessedAction::ExecuteAction() {
  CompilerInstance &CI = getCompilerInstance();
  // Output file needs to be set to 'Binary', to avoid converting Unix style
  // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>).
  llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
  if (!OS) return;

  DoPrintPreprocessedInput(CI.getPreprocessor(), OS,
                           CI.getPreprocessorOutputOpts());
}

void PrintPreambleAction::ExecuteAction() {
  switch (getCurrentFileKind()) {
  case IK_C:
  case IK_CXX:
  case IK_ObjC:
  case IK_ObjCXX:
  case IK_OpenCL:
  case IK_CUDA:
    break;

  case IK_None:
  case IK_Asm:
  case IK_PreprocessedC:
  case IK_PreprocessedCXX:
  case IK_PreprocessedObjC:
  case IK_PreprocessedObjCXX:
  case IK_AST:
  case IK_LLVM_IR:
    // We can't do anything with these.
    return;
  }

  CompilerInstance &CI = getCompilerInstance();
  llvm::MemoryBuffer *Buffer
      = CI.getFileManager().getBufferForFile(getCurrentFile());
  if (Buffer) {
    unsigned Preamble = Lexer::ComputePreamble(Buffer).first;
    llvm::outs().write(Buffer->getBufferStart(), Preamble);
    delete Buffer;
  }
}
<|endoftext|>


<commit_before>/*	opendatacon
 *
 *	Copyright (c) 2014:
 *
 *		DCrip3fJguWgVCLrZFfA7sIGgvx1Ou3fHfCxnrz4svAi
 *		yxeOtDhDCXf1Z4ApgXvX5ahqQmzRfJ2DoX8S05SqHA==
 *
 *	Licensed under the Apache License, Version 2.0 (the "License");
 *	you may not use this file except in compliance with the License.
 *	You may obtain a copy of the License at
 *
 *		http://www.apache.org/licenses/LICENSE-2.0
 *
 *	Unless required by applicable law or agreed to in writing, software
 *	distributed under the License is distributed on an "AS IS" BASIS,
 *	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *	See the License for the specific language governing permissions and
 *	limitations under the License.
 */
/*
 * IOHandler.cpp
 *
 *  Created on: 20/07/2014
 *      Author: Neil Stephens <dearknarl@gmail.com>
 */

#include <opendatacon/IOHandler.h>

namespace odc
{

std::unordered_map<std::string,IOHandler*> IOHandler::IOHandlers;

std::unordered_map<std::string, IOHandler*>& IOHandler::GetIOHandlers()
{
	return IOHandler::IOHandlers;
}

IOHandler::IOHandler(const std::string& aName):
	InitState(InitState_t::ENABLED),
	EnableDelayms(0),
	Name(aName),
	pIOS(nullptr),
	enabled(false)
{
	IOHandlers[Name]=this;
}

void IOHandler::Subscribe(IOHandler* pIOHandler, std::string aName)
{
	this->Subscribers[aName] = pIOHandler;
}

void IOHandler::SetIOS(asio::io_service* ios_ptr)
{
	pIOS = ios_ptr;
}

bool DemandMap::InDemand()
{
	std::lock_guard<std::mutex> lck (mtx);
	for(auto demand : connection_demands)
		if(demand.second)
			return true;
	return false;
}

bool DemandMap::MuxConnectionEvents(ConnectState state, const std::string& SenderName)
{
	if (state == ConnectState::DISCONNECTED)
	{
		{
			std::lock_guard<std::mutex> lck (mtx);
			connection_demands[SenderName] = false;
		}
		return !InDemand();
	}
	else if (state == ConnectState::CONNECTED)
	{
		std::lock_guard<std::mutex> lck (mtx);
		bool new_demand = !connection_demands[SenderName];
		connection_demands[SenderName] = true;
		return new_demand;
	}
	return true;
}

void IOHandler::Event(ConnectState state, const std::string& SenderName)
{
	MuxConnectionEvents(state, SenderName);
}

SharedStatusCallback_t IOHandler::SyncMultiCallback (const size_t cb_number, SharedStatusCallback_t pStatusCallback)
{
	if(pIOS == nullptr)
	{
		throw std::runtime_error("Uninitialised io_service on enabled IOHandler");
	}
	if(cb_number == 1)
		return pStatusCallback;

	auto pCombinedStatus = std::make_shared<CommandStatus>(CommandStatus::SUCCESS);
	auto pExecCount = std::make_shared<size_t>(0);
	auto pCB_sync = std::make_shared<asio::io_service::strand>(*pIOS);
	return std::make_shared<std::function<void (CommandStatus status)>>
		       (pCB_sync->wrap(
				 [pCB_sync,
				  pCombinedStatus,
				  pExecCount,
				  cb_number,
				  pStatusCallback](CommandStatus status)
				 {
					 if(*pCombinedStatus == CommandStatus::UNDEFINED)
						 return;

					 if(++(*pExecCount) == 1)
					 {
					       *pCombinedStatus = status;
					       if(*pCombinedStatus == CommandStatus::UNDEFINED)
					       {
					             (*pStatusCallback)(*pCombinedStatus);
					             return;
						 }
					 }
					 else if(status != *pCombinedStatus)
					 {
					       *pCombinedStatus = CommandStatus::UNDEFINED;
					       (*pStatusCallback)(*pCombinedStatus);
					       return;
					 }

					 if(*pExecCount >= cb_number)
					 {
					       (*pStatusCallback)(*pCombinedStatus);
					 }
				 }));
}

}
<commit_msg>keep the io_service active for the life of the SyncMultiCallback strand/handler<commit_after>/*	opendatacon
 *
 *	Copyright (c) 2014:
 *
 *		DCrip3fJguWgVCLrZFfA7sIGgvx1Ou3fHfCxnrz4svAi
 *		yxeOtDhDCXf1Z4ApgXvX5ahqQmzRfJ2DoX8S05SqHA==
 *
 *	Licensed under the Apache License, Version 2.0 (the "License");
 *	you may not use this file except in compliance with the License.
 *	You may obtain a copy of the License at
 *
 *		http://www.apache.org/licenses/LICENSE-2.0
 *
 *	Unless required by applicable law or agreed to in writing, software
 *	distributed under the License is distributed on an "AS IS" BASIS,
 *	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *	See the License for the specific language governing permissions and
 *	limitations under the License.
 */
/*
 * IOHandler.cpp
 *
 *  Created on: 20/07/2014
 *      Author: Neil Stephens <dearknarl@gmail.com>
 */

#include <opendatacon/IOHandler.h>

namespace odc
{

std::unordered_map<std::string,IOHandler*> IOHandler::IOHandlers;

std::unordered_map<std::string, IOHandler*>& IOHandler::GetIOHandlers()
{
	return IOHandler::IOHandlers;
}

IOHandler::IOHandler(const std::string& aName):
	InitState(InitState_t::ENABLED),
	EnableDelayms(0),
	Name(aName),
	pIOS(nullptr),
	enabled(false)
{
	IOHandlers[Name]=this;
}

void IOHandler::Subscribe(IOHandler* pIOHandler, std::string aName)
{
	this->Subscribers[aName] = pIOHandler;
}

void IOHandler::SetIOS(asio::io_service* ios_ptr)
{
	pIOS = ios_ptr;
}

bool DemandMap::InDemand()
{
	std::lock_guard<std::mutex> lck (mtx);
	for(auto demand : connection_demands)
		if(demand.second)
			return true;
	return false;
}

bool DemandMap::MuxConnectionEvents(ConnectState state, const std::string& SenderName)
{
	if (state == ConnectState::DISCONNECTED)
	{
		{
			std::lock_guard<std::mutex> lck (mtx);
			connection_demands[SenderName] = false;
		}
		return !InDemand();
	}
	else if (state == ConnectState::CONNECTED)
	{
		std::lock_guard<std::mutex> lck (mtx);
		bool new_demand = !connection_demands[SenderName];
		connection_demands[SenderName] = true;
		return new_demand;
	}
	return true;
}

void IOHandler::Event(ConnectState state, const std::string& SenderName)
{
	MuxConnectionEvents(state, SenderName);
}

SharedStatusCallback_t IOHandler::SyncMultiCallback (const size_t cb_number, SharedStatusCallback_t pStatusCallback)
{
	if(pIOS == nullptr)
	{
		throw std::runtime_error("Uninitialised io_service on enabled IOHandler");
	}

	if(cb_number < 2)
		return pStatusCallback;

	//We must keep the io_service active for the life of the strand/handler we're about to create
	auto work = std::make_shared<asio::io_service::work>(*pIOS);
	auto pCombinedStatus = std::make_shared<CommandStatus>(CommandStatus::SUCCESS);
	auto pExecCount = std::make_shared<size_t>(0);
	auto pCB_sync = std::make_shared<asio::io_service::strand>(*pIOS);
	return std::make_shared<std::function<void (CommandStatus status)>>
		       (pCB_sync->wrap(
				 [work,
				  pCB_sync,
				  pCombinedStatus,
				  pExecCount,
				  cb_number,
				  pStatusCallback](CommandStatus status)
				 {
					 if(*pCombinedStatus == CommandStatus::UNDEFINED)
						 return;

					 if(++(*pExecCount) == 1)
					 {
					       *pCombinedStatus = status;
					       if(*pCombinedStatus == CommandStatus::UNDEFINED)
					       {
					             (*pStatusCallback)(*pCombinedStatus);
					             return;
						 }
					 }
					 else if(status != *pCombinedStatus)
					 {
					       *pCombinedStatus = CommandStatus::UNDEFINED;
					       (*pStatusCallback)(*pCombinedStatus);
					       return;
					 }

					 if(*pExecCount >= cb_number)
					 {
					       (*pStatusCallback)(*pCombinedStatus);
					 }
				 }));
}

}
<|endoftext|>