text:
/*
 * Copyright 2017 CERN
 *
 * 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.
 *
 */

/** @file  DomeMetadataCache.hh
 * @brief  In-memory cache of frequently accessed file information
 * @author Fabrizio Furano
 * @date   Mar 2017
 */

#include "DomeMetadataCache.hh"
#include <time.h>
#include <boost/shared_ptr.hpp>
#include <boost/thread/thread_time.hpp>
#include "DomeMysql.h"
#include "status.h"

DomeMetadataCache *DomeMetadataCache::instance = 0;

// ******************************************
// ******************* DomeFileInfo
//

DomeFileInfo::DomeFileInfo(DomeFileID file_id) {

  this->fileid = file_id;
  parentfileid = 0;
  locfilename = "";

  status_statinfo = NoInfo;
  status_locations = NoInfo;

  time_t t = time(0);
  lastupdtime = t;
  lastupdreqtime = t;
  lastreftime = t;

}

DomeFileInfo::DomeFileInfo(DomeFileID parentfid, std::string name) {

  this->fileid = 0;
  this->parentfileid = parentfid;
  locfilename = name;

  status_statinfo = NoInfo;
  status_locations = NoInfo;

  time_t t = time(0);
  lastupdtime = t;
  lastupdreqtime = t;
  lastreftime = t;

}

DomeFileInfo::~DomeFileInfo() {
  Log(Logger::Lvl4, domelogmask, "~DomeFileInfo", "I am being deleted. fileid: " << fileid);
}

void DomeFileInfo::setToNoInfo() {
  const char *fname = "DomeFileInfo::setToNoInfo";
  Log(Logger::Lvl4, domelogmask, fname, "Entering");

  boost::unique_lock<mutex> l2(*this);
  statinfo = dmlite::ExtendedStat();

  status_statinfo = NoInfo;

  replicas.clear();
  status_locations = NoInfo;
}

void DomeFileInfo::takeStat(const dmlite::ExtendedStat &st) {
  const char *fname = "DomeFileInfo::takeStat";
  Log(Logger::Lvl4, domelogmask, fname, st.name << " sz:" << st.stat.st_size << " mode:" << st.stat.st_mode);

  boost::unique_lock<mutex> l2(*this);

  statinfo = st;

  status_statinfo = DomeFileInfo::Ok;

}

void DomeFileInfo::addReplica( const dmlite::Replica & replica ) {
  const char *fname = "DomeFileInfo::addReplica";
  Log(Logger::Lvl4, domelogmask, fname, "Adding replica '" << replica.rfn << "' to fileid " << fileid);

  replicas.push_back(replica);
}

void DomeFileInfo::addReplica( const std::vector<dmlite::Replica> &reps ) {
  const char *fname = "DomeFileInfo::addReplica";
  Log(Logger::Lvl4, domelogmask, fname, "Adding " << replicas.size() << "replicas to fileid " << fileid);

  replicas.insert(replicas.end(), reps.begin(), reps.end());
}

int DomeFileInfo::waitForSomeUpdate(boost::unique_lock<boost::mutex> &l, int sectmout) {

  boost::system_time const timeout = boost::get_system_time() + boost::posix_time::seconds(sectmout);

  if (!condvar.timed_wait(l, timeout))
    return 1; // timeout
  else
    return 0; // signal catched

  return 0;
}

int DomeFileInfo::signalSomeUpdate() {
  condvar.notify_all();

  return 0;
}

int DomeFileInfo::waitStat(boost::unique_lock<boost::mutex> &l, int sectmout)  {
  const char *fname = "DomeFileInfo::waitStat";

  // If it's a cache hit we just exit
  if ((status_statinfo == Ok) || (status_statinfo == NotFound)) {
    Log(Logger::Lvl4, domelogmask, fname, "Info found. Fileid: " << fileid <<
    " status_statinfo: " << status_statinfo);

    return 1;
  }

  // By convention, if there is noinfo then it's our responsibility to fill it, hence it becomes pending
  if (status_statinfo == NoInfo) {
    Log(Logger::Lvl4, domelogmask, fname, "Shall fill stat info. Fileid: " << fileid <<
    "parent_fileid: " << parentfileid << " locfilename: '" << locfilename <<
    "' status_statinfo: " << status_statinfo);

    status_statinfo = InProgress;

    return 0;
  }

  // If still pending, we wait for the file object to get a notification
  // then we recheck...
  time_t timelimit = time(0) + sectmout;

  Log(Logger::Lvl4, domelogmask, fname, "Starting check-wait. Fileid: " << fileid <<
  "parent_fileid: " << parentfileid << " locfilename: '" << locfilename <<
  "' status_statinfo: " << status_statinfo << "'");

  while (status_statinfo == InProgress) {
    // Ignore the timeouts, exit only on an explicit notification
    waitForSomeUpdate(l, 1);
    // On global timeout... stop waiting
    if (time(0) > timelimit) {
      Log(Logger::Lvl1, domelogmask, fname, "Timeout. Fileid:" << fileid <<
      "parent_fileid: " << parentfileid << " locfilename: '" << locfilename << "'");
      break;
    }
  }

  Log(Logger::Lvl3, domelogmask, fname, "Finished check-wait. Fileid: " << fileid <<
  "parent_fileid: " << parentfileid << " locfilename: '" << locfilename <<
  "' status_statinfo: " << status_statinfo);

  // We are here if someone else's lookup has finished OR in the case of timeout
  // If the stat is still marked as in progress it means that the information was not filled
  if (status_statinfo == InProgress)
    return 2;

  // If it's a cache hit we just exit
  if ((status_statinfo == Ok) || (status_statinfo == NotFound)) {
    Log(Logger::Lvl4, domelogmask, fname, "Info found. Fileid: " << fileid <<
    " status_statinfo: " << status_statinfo);

    return 1;
  }

  return 3;
}

int DomeFileInfo::waitLocations(boost::unique_lock<boost::mutex> &l, int sectmout)  {
  const char *fname = "DomeFileInfo::waitLocations";

  // If it's a cache hit we just exit
  if ((status_locations == Ok) || (status_locations == NotFound)) {
    Log(Logger::Lvl4, domelogmask, fname, "Info found. Fileid: " << fileid <<
    " status_statinfo: " << status_statinfo << " status_locations: " << status_locations);

    return 1;
  }

  // By convention, if there is noinfo then it's our responsibility to fill it, hence it becomes pending
  if (status_locations == NoInfo) {
    Log(Logger::Lvl4, domelogmask, fname, "Shall fill locations info. Fileid: " << fileid <<
    "parent_fileid: " << parentfileid << " locfilename: '" << locfilename <<
    "' status_statinfo: " << status_statinfo << " status_locations: " << status_locations);

    status_locations = InProgress;

    return 0;
  }

  // If still pending, we wait for the file object to get a notification
  // then we recheck...
  time_t timelimit = time(0) + sectmout;

  Log(Logger::Lvl4, domelogmask, fname, "Starting check-wait. Fileid: " << fileid <<
  "parent_fileid: " << parentfileid << " locfilename: '" << locfilename <<
  "' status_statinfo: " << status_statinfo << " status_locations: " << status_locations);

  while (status_statinfo == InProgress) {
    // Ignore the timeouts, exit only on an explicit notification
    waitForSomeUpdate(l, 1);
    // On global timeout... stop waiting
    if (time(0) > timelimit) {
      Log(Logger::Lvl1, domelogmask, fname, "Timeout. Fileid:" << fileid <<
      "parent_fileid: " << parentfileid << " locfilename: '" << locfilename << "'");
      break;
    }
  }

  Log(Logger::Lvl3, domelogmask, fname, "Finished check-wait. Fileid: " << fileid <<
  "parent_fileid: " << parentfileid << " locfilename: '" << locfilename <<
  "' status_statinfo: " << status_statinfo << " status_locations: " << status_locations);

  // We are here if someone else's lookup has finished OR in the case of timeout
  // If the stat is still marked as in progress it means that the information was not filled
  if (status_locations == InProgress)
    return 2;

  // If it's a cache hit we just exit
  if ((status_locations == Ok) || (status_locations == NotFound)) {
    Log(Logger::Lvl4, domelogmask, fname, "Info found. Fileid: " << fileid <<
    " status_statinfo: " << status_statinfo << " status_locations: " << status_locations);

    return 1;
  }

  return 3;
}

//
// ******************************************
// ******************* DomeMetadataCache
//

// Purge the least recently used element
// Returns 0 if the element was purged, non0 if it was not possible

int DomeMetadataCache::purgeLRUitem_fileid() {
  const char *fname = "DomeMetadataCache::purgeLRUitem";

  {
    // No LRU item, the LRU list is empty
    if (lrudata.empty()) {
      Log(Logger::Lvl4, domelogmask, fname, "LRU list is empty. Nothing to purge.");
      return 1;
    }

    // Take the key of the lru item
    DomeFileID s = lrudata.left.begin()->second;
    Log(Logger::Lvl4, domelogmask, fname, "LRU item is fileid " << s);

    // Lookup its instance in the cache
    boost::shared_ptr<DomeFileInfo> fi = databyfileid[s];

    if (!fi) {
      Err(fname, "Could not find the LRU item in the cache. Fixing the internal inconsistency.");

      // Purge it from the lru list
      lrudata.right.erase(s);

      return 2;
    }

    {
      boost::unique_lock<mutex> lck(*fi);
      if ( (fi->status_statinfo == DomeFileInfo::InProgress) ||
        (fi->status_locations == DomeFileInfo::InProgress) ) {
        Log(Logger::Lvl4, domelogmask, fname, "The LRU item is marked as pending. Cannot purge fileid " << fi->fileid);
        return 3;
      }

    }

    // We have decided that we can delete it...

    // Purge it from the lru list
    lrudata.right.erase(s);

    // Remove the item from the map
    databyfileid.erase(s);

    // The object will be deleted as soon as all the references to it disappear
  }

  return 0;
}

int DomeMetadataCache::purgeLRUitem_parent() {
  const char *fname = "DomeMetadataCache::purgeLRUitem";

  {
    // No LRU item, the LRU list is empty
    if (lrudata_parent.empty()) {
      Log(Logger::Lvl4, domelogmask, fname, "LRU_parent list is empty. Nothing to purge.");
      return 1;
    }

    // Take the key of the lru item
    DomeFileInfoParent s = lrudata_parent.left.begin()->second;
    Log(Logger::Lvl4, domelogmask, fname, "LRU_parent item is " << s.parentfileid << "'" << s.name << "'");

    // Lookup its instance in the cache
    boost::shared_ptr<DomeFileInfo> fi = databyparent[s];

    if (!fi) {
      Err(fname, "Could not find the LRU_parent item in the cache. Fixing.");
      lrudata_parent.right.erase(s);
      return 2;
    }

    {
      boost::unique_lock<mutex> lck(*fi);
      if ( (fi->status_statinfo == DomeFileInfo::InProgress) ||
        (fi->status_locations == DomeFileInfo::InProgress) ) {
        Log(Logger::Lvl4, domelogmask, fname, "The LRU item is marked as pending. Cannot purge " << fi->fileid);
        return 3;
      }

    }

    // We have decided that we can delete it...

    // Purge it from the lru list
    lrudata_parent.right.erase(s);

    // Remove the item from the map
    databyparent.erase(s);

    // The object will be deleted as soon as all the references to it disappear
  }
  return 0;
}

// Purge the items that were not touched since a longer time

void DomeMetadataCache::purgeExpired_fileid() {
  const char *fname = "DomeMetadataCache::purgeExpired";
  int d = 0;
  time_t timelimit = time(0) - maxttl;
  time_t timelimit_max = time(0) - maxmaxttl;
  time_t timelimit_neg = time(0) - maxttl_negative;

  bool dodelete = false;
  std::map< DomeFileID, boost::shared_ptr<DomeFileInfo> >::iterator i_deleteme;

  for (std::map< DomeFileID, boost::shared_ptr<DomeFileInfo> >::iterator i = databyfileid.begin();
       i != databyfileid.end(); i++) {

    if (dodelete) {
      databyfileid.erase(i_deleteme);
      dodelete = false;
    }
    dodelete = false;

  boost::shared_ptr<DomeFileInfo> fi = i->second;

  if (fi) {

    {
      boost::unique_lock<mutex> lck(*fi);

      time_t tl = timelimit;
      if ( (fi->status_statinfo == DomeFileInfo::NotFound) ||
        (fi->status_locations == DomeFileInfo::NotFound) ) {
        tl = timelimit_neg;
      }

      if ((fi->lastreftime < tl) || (fi->lastreftime < timelimit_max)) {
        // The item is old...

        if ( (fi->status_statinfo == DomeFileInfo::InProgress) ||
          (fi->status_locations == DomeFileInfo::InProgress) ) {
          Err(fname, "Found pending expired entry. Cannot purge fileid " << fi->statinfo.stat.st_ino);
          continue;
        }

        if (Logger::get()->getLevel() >= 4)
          Log(Logger::Lvl4, domelogmask, fname, "purging expired fileid " << fi->statinfo.stat.st_ino <<
            " name: '" << fi->statinfo.name << "' status_statinfo: " << fi->status_statinfo <<
            " status_locations: " << fi->status_locations <<
            " lastreftime: " << fi->lastreftime << " timelimit: " << tl << " timelimit_max: " << timelimit_max);
        else
          Log(Logger::Lvl2, domelogmask, fname, "purging expired fileid " << fi->statinfo.stat.st_ino <<
            " name: '" << fi->statinfo.name << "'");

        lrudata.right.erase(fi->statinfo.stat.st_ino);

        DomeFileInfoParent k;
        k.name = fi->statinfo.name;
        k.parentfileid = fi->statinfo.parent;
        lrudata_parent.right.erase(k);

        dodelete = true;
        i_deleteme = i;

        d++;

      }
    }

    // The entry will disappear when there are no more references to it

  }

       }

       if (dodelete) {
         databyfileid.erase(i_deleteme);
         dodelete = false;
       }

       if (d > 0)
         Log(Logger::Lvl1, domelogmask, fname, "purged " << d << " expired items.");
}

void DomeMetadataCache::purgeExpired_parent() {
  const char *fname = "DomeMetadataCache::purgeExpired_parent";
  int d = 0;
  time_t timelimit = time(0) - maxttl;
  time_t timelimit_max = time(0) - maxmaxttl;
  time_t timelimit_neg = time(0) - maxttl_negative;

  bool dodelete = false;
  std::map< DomeFileInfoParent, boost::shared_ptr<DomeFileInfo>,  DomeFileInfoParentComp>::iterator i_deleteme;

  for (std::map< DomeFileInfoParent, boost::shared_ptr<DomeFileInfo>,  DomeFileInfoParentComp>::iterator i = databyparent.begin();
       i != databyparent.end(); i++) {

    if (dodelete) {
      databyparent.erase(i_deleteme);
      dodelete = false;
    }
    dodelete = false;

  boost::shared_ptr<DomeFileInfo> fi = i->second;

  if (fi) {

    {
      boost::unique_lock<mutex> lck(*fi);

      time_t tl = timelimit;
      if ( (fi->status_statinfo == DomeFileInfo::NotFound) ||
        (fi->status_locations == DomeFileInfo::NotFound) ) {
        tl = timelimit_neg;
      }

      if ((fi->lastreftime < tl) || (fi->lastreftime < timelimit_max)) {
        // The item is old...

        if ( (fi->status_statinfo == DomeFileInfo::InProgress) ||
          (fi->status_locations == DomeFileInfo::InProgress) ) {
          Err(fname, "Found pending expired entry. Cannot purge parentfileid " << fi->statinfo.parent << "'" << fi->statinfo.name << "'");
          continue;
        }

        if (Logger::get()->getLevel() >= 4)
          Log(Logger::Lvl4, domelogmask, fname, "purging expired parentfileid " << fi->statinfo.parent <<
            " name: '" << fi->statinfo.name << "' status_statinfo: " << fi->status_statinfo <<
            " status_locations: " << fi->status_locations <<
            " lastreftime: " << fi->lastreftime << " timelimit: " << tl << " timelimit_max: " << timelimit_max);
        else
          Log(Logger::Lvl2, domelogmask, fname, "purging expired parentfileid " << fi->statinfo.parent << "'" << fi->statinfo.name << "'");

        lrudata.right.erase(fi->statinfo.stat.st_ino);

        DomeFileInfoParent k;
        k.name = fi->statinfo.name;
        k.parentfileid = fi->statinfo.parent;
        lrudata_parent.right.erase(k);

        dodelete = true;
        i_deleteme = i;

        d++;

      }
    }

    // The entry will disappear when there are no more references to it

  }

       }

       if (dodelete) {
         databyparent.erase(i_deleteme);
         dodelete = false;
       }

       if (d > 0)
         Log(Logger::Lvl1, domelogmask, fname, "purged " << d << " expired items.");
}

boost::shared_ptr <DomeFileInfo > DomeMetadataCache::getFileInfoOrCreateNewOne(DomeFileID fileid) {
  const char *fname = "DomeMetadataCache::getFileInfoOrCreateNewOne";
  boost::shared_ptr <DomeFileInfo > fi;
  bool hit = true;

  Log(Logger::Lvl4, domelogmask, fname, "fileid: " << fileid);

  {
    boost::lock_guard<DomeMetadataCache> l(*this);

    std::map< DomeFileID, boost::shared_ptr<DomeFileInfo> >::iterator p;

    p = databyfileid.find(fileid);
    if (p == databyfileid.end()) {

      // If we still have no space, try to garbage collect the old items
      if (databyfileid.size() > maxitems) {
        Log(Logger::Lvl4, domelogmask, fname, "Too many items " << databyfileid.size() << ">" << maxitems << ", running fileid garbage collection...");
        purgeExpired_fileid();
      }

      // If we reached the max number of items, delete as many as we need
      while (databyfileid.size() > maxitems) {
        Log(Logger::Lvl4, domelogmask, fname, "Too many items " << databyfileid.size() << ">" << maxitems << ", purging fileid LRU items...");
        if (purgeLRUitem_fileid()) break;
      }

      // If we still have no space, complain and do it anyway.
      if (databyfileid.size() > maxitems) {
        Log(Logger::Lvl4, domelogmask, fname, "Maximum fileid cache capacity exceeded. " << databyfileid.size() << ">" << maxitems);
      }

      // Create a new empty item
      fi.reset( new DomeFileInfo(fileid) );
      hit = false;
      // To disable the cache, set maxitems to 0
      if (maxitems > 0) {
        databyfileid[fileid] = boost::shared_ptr <DomeFileInfo >(fi);
        lrudata.insert(lrudataitem(++lrutick, fileid));
      }

    } else {
      // Promote the element to being the most recently used
      // Don't make it pending, not needed here
      lrudata.right.erase(fileid);
      lrudata.insert(lrudataitem(++lrutick, fileid));
      fi = p->second;
      fi->touch();
    }
  }

  // Here we have either
  //  - a new empty UgrFileInfo
  //  - an UgrFileInfo taken from the 1st level cache
  if (hit)
    Log(Logger::Lvl3, domelogmask, fname, "Exiting (hit). fileid: " << fileid << " addr: " << fi);
  else
    Log(Logger::Lvl3, domelogmask, fname, "Exiting (miss). fileid: " << fileid << " addr: " << fi);

  return fi;

}

boost::shared_ptr<DomeFileInfo> DomeMetadataCache::getFileInfoOrCreateNewOne(DomeFileID parentfileid, std::string name) {
  const char *fname = "DomeMetadataCache::getFileInfoOrCreateNewOne(parent)";
  boost::shared_ptr<DomeFileInfo> fi;
  bool hit = true;

  Log(Logger::Lvl4, domelogmask, fname, "parentfileid: " << parentfileid << " name: '" << name << "'");

  DomeFileInfoParent k;
  k.name = name;
  k.parentfileid = parentfileid;

  {
    boost::lock_guard<DomeMetadataCache> l(*this);

    std::map< DomeFileInfoParent, boost::shared_ptr<DomeFileInfo>,  DomeFileInfoParentComp>::iterator p;

    p = databyparent.find(k);
    if (p == databyparent.end()) {

      // If we still have no space, try to garbage collect the old items
      if (databyparent.size() > maxitems) {
        Log(Logger::Lvl4, domelogmask, fname, "Too many items " << databyparent.size() << ">" << maxitems << ", running parent garbage collection...");
        purgeExpired_parent();
      }

      // If we reached the max number of items, delete as many as we need
      while (databyparent.size() > maxitems) {
        Log(Logger::Lvl4, domelogmask, fname, "Too many items " << databyparent.size() << ">" << maxitems << ", purging parent LRU items...");
        if (purgeLRUitem_parent()) break;
      }

      // If we still have no space, complain and do it anyway.
      if (databyparent.size() > maxitems) {
        Log(Logger::Lvl4, domelogmask, fname, "Maximum parent cache capacity exceeded. " << databyparent.size() << ">" << maxitems);
      }

      // Create a new item
      fi.reset( new DomeFileInfo(parentfileid, name) );
      hit = false;

      // To disable the cache, set maxitems to 0
      if (maxitems > 0) {
        databyparent[k] = fi;
        lrudata_parent.insert(lrudataitem_parent(++lrutick, k));
      }

    } else {
      // Promote the element to being the most recently used
      // Don't make it pending, not needed here
      lrudata_parent.right.erase(k);
      lrudata_parent.insert(lrudataitem_parent(++lrutick, k));
      fi = p->second;
      fi->touch();
    }
  }

  // Here we have either
  //  - a new empty UgrFileInfo, marked as pending for both statinfo and locations
  //  - an UgrFileInfo taken from the 1st level cache

  if (hit)
    Log(Logger::Lvl3, domelogmask, fname, "Exiting (hit). parentfileid: " << parentfileid << " name: '" << name << "'");
  else
    Log(Logger::Lvl3, domelogmask, fname, "Exiting (miss). parentfileid: " << parentfileid << " name: '" << name << "'");

  return fi;

}

void DomeMetadataCache::tick() {
  const char *fname = "DomeMetadataCache::tick";
  Log(Logger::Lvl4, domelogmask, fname, "tick...");

  boost::lock_guard<DomeMetadataCache> l(*this);

  purgeExpired();

  // If we reached the max number of items, delete as much as we can
  while (databyfileid.size() > maxitems) {
    if (purgeLRUitem_fileid()) break;
  }
  while (databyparent.size() > maxitems) {
    if (purgeLRUitem_parent()) break;
  }

  Log(Logger::Lvl4, domelogmask, fname, "Cache status by fileid. nItems:" << databyfileid.size() << " nLRUItems: " << lrudata.size());
  Log(Logger::Lvl4, domelogmask, fname, "Cache status by parentid+name. nItems:" << databyparent.size() << " nLRUItems: " << lrudata_parent.size());

}

/// Tag an entry so that it will be soon purged
void DomeMetadataCache::wipeEntry(dmlite::ExtendedStat xstat) {
  wipeEntry(xstat.stat.st_ino, xstat.parent, xstat.name);
}

/// Tag an entry so that it will be soon purged. More expensive version that does a stat inside
void DomeMetadataCache::wipeEntry(DomeFileID fileid) {
  const char *fname = "DomeMetadataCache::wipeEntry";
  Log(Logger::Lvl4, domelogmask, fname, "fileid: " << fileid);

  dmlite::ExtendedStat xstat;
  xstat.parent = 0;
  xstat.name = "";
  DomeMySql sql;

  sql.getStatbyFileid(xstat, fileid);

  wipeEntry(xstat.stat.st_ino, xstat.parent, xstat.name);

}

/// Tag an entry so that it will be soon purged
void DomeMetadataCache::wipeEntry(DomeFileID fileid, DomeFileID parentfileid, std::string name) {
  const char *fname = "DomeMetadataCache::wipeEntry";
  Log(Logger::Lvl4, domelogmask, fname, "fileid: " << fileid << " parentfileid: " << parentfileid << " name: '" << name << "'");

  boost::lock_guard<DomeMetadataCache> l(*this);

  {
    std::map< DomeFileID, boost::shared_ptr<DomeFileInfo> >::iterator p;

    // Fix the item got through the fileid
    p = databyfileid.find(fileid);
    if (p != databyfileid.end()) {
      Log(Logger::Lvl4, domelogmask, fname, "Found fileid: " << fileid << " addr: " << p->second);
      boost::shared_ptr<DomeFileInfo> fi;
      fi = p->second;

      boost::unique_lock<boost::mutex> l(*fi);
      fi->status_statinfo = DomeFileInfo::NoInfo;
      fi->status_locations = DomeFileInfo::NoInfo;
      fi->replicas.clear();
      fi->signalSomeUpdate();
    }
  }

  if (name.length() || (parentfileid > 0)) {
    // Fix the item got through the parentfileid+name
    DomeFileInfoParent k;
    k.name = name;
    k.parentfileid = parentfileid;

    std::map< DomeFileInfoParent, boost::shared_ptr<DomeFileInfo> >::iterator p;
    p = databyparent.find(k);
    if (p != databyparent.end()) {
      Log(Logger::Lvl4, domelogmask, fname, "Found parentfileid: " << parentfileid << " name: '" << name << "'" << " addr: " << p->second);
      boost::shared_ptr<DomeFileInfo> fi;
      fi = p->second;

      boost::unique_lock<boost::mutex> l(*fi);
      fi->status_statinfo = DomeFileInfo::NoInfo;
      fi->status_locations = DomeFileInfo::NoInfo;
      fi->replicas.clear();
      fi->signalSomeUpdate();
    }
  }

  Log(Logger::Lvl3, domelogmask, fname, "Exiting. fileid: " << fileid << " parentfileid: " << parentfileid << " name: '" << name << "'");
  return;
}

int DomeMetadataCache::pushXstatInfo(dmlite::ExtendedStat xstat, DomeFileInfo::InfoStatus newstatus_statinfo) {
  const char *fname = "DomeMetadataCache::pushXstatInfo";

  Log(Logger::Lvl4, domelogmask, fname, "Adjusting fileid: " << xstat.stat.st_ino << " parentfileid: " <<
  xstat.parent << " name: '" << xstat.name << "'");

  boost::shared_ptr <DomeFileInfo > fi;

  boost::lock_guard<DomeMetadataCache> l(*this);
  {
    // Fix the item got through the parentfileid+name
    DomeFileInfoParent k;
    k.name = xstat.name;
    k.parentfileid = xstat.parent;

    std::map< DomeFileInfoParent, boost::shared_ptr<DomeFileInfo> >::iterator p;
    p = databyparent.find(k);
    if (p != databyparent.end()) {
      Log(Logger::Lvl4, domelogmask, fname, "Adjusting parentfileid: " << xstat.parent << " name: '" << xstat.name << "'");

      fi = p->second;

      boost::unique_lock<boost::mutex> l(*fi);
      fi->statinfo = xstat;
      fi->status_statinfo = newstatus_statinfo;
      fi->parentfileid = xstat.parent;
      fi->signalSomeUpdate();
    }
    else {
      // Create a new item
      fi.reset( new DomeFileInfo(xstat.parent, xstat.name) );

      DomeFileInfoParent k;
      k.name = xstat.name;
      k.parentfileid = xstat.parent;

      fi->statinfo = xstat;
      fi->status_statinfo = DomeFileInfo::Ok;
      // To disable the cache, set maxitems to 0
      if (maxitems > 0) {
        databyparent[k] = fi;
        lrudata_parent.insert(lrudataitem_parent(++lrutick, k));
      }
    }

    {
      std::map< DomeFileID, boost::shared_ptr<DomeFileInfo> >::iterator p;

      // Fix the item got through the fileid
      p = databyfileid.find(xstat.stat.st_ino);
      if (p != databyfileid.end()) {
        Log(Logger::Lvl4, domelogmask, fname, "Adjusting fileid: " << xstat.stat.st_ino );

        fi = p->second;

        boost::unique_lock<boost::mutex> l(*fi);
        fi->statinfo = xstat;
        fi->status_statinfo = newstatus_statinfo;
        fi->fileid = xstat.stat.st_ino;
        fi->signalSomeUpdate();
      }
      else {
        // Create a new item if fi has not been set
        if (!fi)
          fi.reset( new DomeFileInfo(xstat.stat.st_ino) );

        fi->statinfo = xstat;
        fi->status_statinfo = DomeFileInfo::Ok;
        // To disable the cache, set maxitems to 0
        if (maxitems > 0) {
          databyfileid[xstat.stat.st_ino] = fi;
          lrudata.insert(lrudataitem(++lrutick, xstat.stat.st_ino));
        }
      }
    }

  }

  Log(Logger::Lvl3, domelogmask, fname, "Exiting. fileid: " << xstat.stat.st_ino << " parentfileid: " <<
  xstat.parent << " name: '" << xstat.name << "'");
  return 0;
}

int DomeMetadataCache::removeInfo(DomeFileID fileid, DomeFileID parentfileid, std::string name) {
  const char *fname = "DomeMetadataCache::removeInfo";

  Log(Logger::Lvl4, domelogmask, fname, "Removing fileid: " << fileid << " parentfileid: " <<
  parentfileid << " name: '" << name << "'");

  boost::lock_guard<DomeMetadataCache> l(*this);
  {
    // Remove the item got through the parentfileid+name
    DomeFileInfoParent k;
    k.name = name;
    k.parentfileid = parentfileid;

    databyparent.erase(k);

    // Remove the item got through the fileid
    databyfileid.erase(fileid);

  }

  Log(Logger::Lvl3, domelogmask, fname, "Exiting. fileid: " << fileid << " parentfileid: " <<
  parentfileid << " name: '" << name << "'");
  return 0;
}

max_stars_repo_name: EricKTCheung/dmlite

max_issues_repo_name: EricKTCheung/dmlite

max_forks_repo_name: EricKTCheung/dmlite


text:
/***************************************************************************
   Copyright 2015 Ufora Inc.

   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.
****************************************************************************/
#pragma once

#include "Queue.hpp"
#include "../Logging.hpp"
#include "../Clock.hpp"
#include <boost/thread.hpp>

class LimitToTime {
public:
	LimitToTime(double maxTime)
		{
		curQueue().write(std::make_pair(this, curClock() + maxTime));
		ensureStarted();
		}

	~LimitToTime()
		{
		curQueue().write(std::make_pair(this, 0));
		}

private:
	static void threadLoop()
		{
		std::map<LimitToTime*, double> timeouts;

		while (true)
			{
			std::pair<LimitToTime*, double> timeout;

			if (curQueue().getTimeout(timeout, 1))
				{
				if (timeouts.find(timeout.first) == timeouts.end())
					timeouts[timeout.first] = timeout.second;
				else
					timeouts.erase(timeout.first);
				}

			for (auto timeoutAndTime: timeouts)
				if (curClock() > timeoutAndTime.second)
					{
					LOG_CRITICAL << "Timed out!";
					fflush(stdout);
					fflush(stderr);

					asm("int3");
					}
			}
		}

	static void ensureStarted()
		{
		static bool isStarted = false;
		static boost::mutex mutex;

		boost::mutex::scoped_lock lock(mutex);
		if (!isStarted)
			{
			boost::thread(&threadLoop).detach();
			isStarted = true;
			}
		}

	static Queue<std::pair<LimitToTime*, double> >& curQueue()
		{
		static Queue<std::pair<LimitToTime*, double> > queue;

		return queue;
		}
};

ext: hpp

max_stars_repo_name: ufora/ufora


text:
// Copyright (c) 2012-2017, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2018-2020, The Qwertycoin developers
//
// This file is part of Qwertycoin.
//
// Qwertycoin is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Qwertycoin is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Qwertycoin.  If not, see <http://www.gnu.org/licenses/>.

#include <boost/utility/value_init.hpp>

#include <Common/Util.h>

#include <CryptoNoteCore/Blockchain/BlockIndex.h>

#include <Serialization/CryptoNoteSerialization.h>
#include <Serialization/SerializationOverloads.h>

namespace CryptoNote {
    Crypto::Hash BlockIndex::getBlockId(uint32_t height) const
    {
        return mContainer[static_cast<size_t>(height)];
    }

    std::vector<Crypto::Hash> BlockIndex::getBlockIds(uint32_t startBlockIndex,
                                                      uint32_t maxCount) const
    {
        std::vector<Crypto::Hash> result;
        if (startBlockIndex >= mContainer.size()) {
            return result;
        }

        size_t count = std::min(static_cast<size_t>(maxCount),
                                mContainer.size() - static_cast<size_t>(startBlockIndex));
        result.reserve(count);
        for (size_t i = 0; i < count; ++i) {
            result.push_back(mContainer[startBlockIndex + i]);
        }

        return result;
    }

    std::vector<Crypto::Hash> BlockIndex::getBlockIds(uint32_t startBlockIndex,
                                                      uint32_t maxCount,
                                                      BlockchainDB &db) const
    {
        std::vector<Crypto::Hash> result;
        if (startBlockIndex >= mContainer.size()) {
            return result;
        }

        size_t count = std::min(static_cast<size_t>(maxCount),
                                mContainer.size() - static_cast<size_t>(startBlockIndex));
        result.reserve(count);
        for (size_t i = 0; i < count; ++i) {
            result.push_back(mContainer[startBlockIndex + i]);
        }

        return result;
    }

    bool BlockIndex::findSupplement(const std::vector<Crypto::Hash> &ids,
                                    uint32_t &offset) const
    {
        for (const auto &id : ids) {
            if (getBlockHeight(id, offset)) {
                return true;
            }
        }

        return false;
    }

    bool BlockIndex::findSupplement(const std::vector<Crypto::Hash> &ids,
                                    uint32_t &offset,
                                    BlockchainDB &db) const
    {
        /*!
         * TODO: Check if this should return a vector by reference for offset
         */
        for (const auto &id : ids) {
            try {
                offset = db.getBlockHeight(id);
            } catch (...) {
                std::exception e;
                throw e;
                return false;
            }

            return true;
        }

        return false;
    }

    std::vector<Crypto::Hash> BlockIndex::buildSparseChain(const Crypto::Hash &startBlockId) const
    {
        uint32_t startBlockHeight;
        getBlockHeight(startBlockId, startBlockHeight);
        std::vector<Crypto::Hash> result;
        size_t sparceChainEnd = static_cast<size_t>(startBlockHeight + 1);
        for (size_t i = 1; i <= sparceChainEnd; i *= 2) {
            result.emplace_back(mContainer[sparceChainEnd - i]);
        }

        if (result.back() != mContainer[0]) {
            result.emplace_back(mContainer[0]);
        }

        return result;
    }

    std::vector<Crypto::Hash> BlockIndex::buildSparseChain(const Crypto::Hash &startBlockId,
                                                           BlockchainDB &db) const
    {
        uint32_t startBlockHeight = db.getBlockHeight(startBlockId);

        std::vector<Crypto::Hash> result;
        size_t sparseChainEnd = static_cast<size_t>(startBlockHeight + 1);
        for (size_t i = 1; i <= sparseChainEnd; i *= 2) {
            result.emplace_back(db.getBlockHashFromHeight(sparseChainEnd - i));
        }

        if (result.back() != mContainer[0]) {
            result.emplace_back(mContainer[0]);
        }

        return result;
    }

    Crypto::Hash BlockIndex::getTailId() const
    {
        assert(!mContainer.empty());
        return mContainer.back();
    }

    void BlockIndex::serialize(ISerializer &s)
    {
        if (s.type() == ISerializer::INPUT) {
            readSequence<Crypto::Hash>(std::back_inserter(mContainer),
                                                          "index",
                                                          s);
        } else {
            writeSequence<Crypto::Hash>(mContainer.begin(),
                                        mContainer.end(),
                                        "index",
                                        s);
        }
    }

} // namespace CryptoNote

ext: cpp

max_stars_repo_name: exploshot/qwc-test

max_issues_repo_name: exploshot/qwc-test

max_forks_repo_name: exploshot/qwc-test


text:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- vim:set ts=4 sw=4 sts=4 noet: */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>

#include <boost/program_options.hpp>

#include "flint/numeric.h"
#include "isd2csv.h"

namespace po = boost::program_options;

using namespace flint;

int main(int argc, char *argv[])
{
	po::options_description opts("options");
	po::positional_options_description popts;
	po::variables_map vm;
	std::string input_file, output_file;
	int print_help = 0;
	isd2csv::Option option;

	opts.add_options()
		("help,h", "Show this message")
		("progress", po::value<std::string>(&option.port)->default_value(""), "Send progress in percentage")
		("ignore-prefixes,P", "Ignore variable prefixes")
		("ignore-units,U", "Ignore units")
		("maximum-precision,M", "Request the maximum number of decimal digits to print double-precision floating-point numbers")
		("output,o", po::value<std::string>(&output_file), "Output file name")
		("input", po::value<std::string>(&input_file), "Input file name");
	popts.add("input", 1);

	try {
		po::store(po::command_line_parser(argc, argv).options(opts).positional(popts).run(), vm);
		po::notify(vm);
		if (vm.count("help")) print_help = 1;
	} catch (const po::error &) {
		print_help = 2;
	}
	if (print_help != 0) {
		std::cerr << "usage: isd2csv [OPTIONS] [PATH]" << std::endl;
		std::cerr << opts;
		return (print_help == 1) ? EXIT_SUCCESS : EXIT_FAILURE;
	}

	int r;
	option.ignore_prefixes = (vm.count("ignore-prefixes") > 0);
	option.ignore_units = (vm.count("ignore-units") > 0);
	if (vm.count("output")) {
		std::ofstream ofs(output_file.c_str(), std::ios::out|std::ios::binary);
		if (!ofs.is_open()) {
			std::cerr << "could not open output file: " << output_file << std::endl;
			return EXIT_FAILURE;
		}
		if (vm.count("maximum-precision"))
			RequestMaxNumOfDigitsForDouble(ofs);
		if (vm.count("input")) {
			std::ifstream ifs(input_file.c_str(), std::ios::in|std::ios::binary);
			if (!ifs.is_open()) {
				std::cerr << "could not open input file: " << input_file << std::endl;
				return EXIT_FAILURE;
			}
			r = isd2csv::Convert(option, &ifs, &ofs);
			ifs.close();
		} else {
			r = isd2csv::Convert(option, &std::cin, &ofs);
		}
		ofs.close();
	} else {
		if (vm.count("maximum-precision"))
			RequestMaxNumOfDigitsForDouble(std::cout);
		if (vm.count("input")) {
			std::ifstream ifs(input_file.c_str(), std::ios::in|std::ios::binary);
			if (!ifs.is_open()) {
				std::cerr << "could not open input file: " << input_file << std::endl;
				return EXIT_FAILURE;
			}
			r = isd2csv::Convert(option, &ifs, &std::cout);
			ifs.close();
		} else {
			r = isd2csv::Convert(option, &std::cin, &std::cout);
		}
	}
	return r;
}

ext: cc

max_stars_repo_name: Abhisheknishant/Flint

max_issues_repo_name: Abhisheknishant/Flint

max_forks_repo_name: Abhisheknishant/Flint


text:
/* Copyright Institute of Sound and Vibration Research - All rights reserved */

#ifndef VISR_LIBRRL_PARAMETER_CONNECTION_GRAPH_HPP_INCLUDED
#define VISR_LIBRRL_PARAMETER_CONNECTION_GRAPH_HPP_INCLUDED

#include "parameter_connection_map.hpp"

#include <libvisr/constants.hpp>

#include <ciso646>
#include <iosfwd>
#include <set>
#include <memory>
#include <stdexcept>
#include <vector>

#include <boost/graph/adjacency_list.hpp>

namespace visr
{
// Forward declarations
namespace impl
{
class ParameterPortBaseImplementation;
}

namespace rrl
{

class ParameterConnectionGraph
{
public:
  class ConnectedPorts
  {
    friend class ParameterConnectionGraph;
  public:
    using Ports = std::vector< impl::ParameterPortBaseImplementation * >;

    ConnectedPorts() {}

    Ports const & receivePorts() const { return mReceivePorts; }
    Ports const & sendPorts() const { return mSendPorts; }

    std::size_t numSenders() const { return mSendPorts.size(); }
    std::size_t numReceivers() const { return mSendPorts.size(); }

  private:
    Ports mSendPorts;
    Ports mReceivePorts;
  };

  using ConnectedPortVector = std::vector< ConnectedPorts >;

  explicit ParameterConnectionGraph( ParameterConnectionMap const & connections );

  /**
   * Destructor.
   */
  ~ParameterConnectionGraph( );

  ConnectedPortVector const & connectedPorts() const { return mConnections; }

private:

  using GraphType = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, impl::ParameterPortBaseImplementation * >;

  GraphType mConnectionGraph;

  using VertexMap = std::map<impl::ParameterPortBaseImplementation *, GraphType::vertex_descriptor >;

  VertexMap mVertexLookup;

  ConnectedPortVector mConnections;
};

} // namespace rrl
} // namespace visr

#endif // #ifndef VISR_LIBRRL_PARAMETER_CONNECTION_GRAPH_HPP_INCLUDED


text:
#ifndef QUBUS_VARIABLE_ACCESS_ANALYSIS_HPP
#define QUBUS_VARIABLE_ACCESS_ANALYSIS_HPP

#include <qubus/pass_manager.hpp>

#include <qubus/IR/access_qualifier.hpp>
#include <qubus/IR/expression.hpp>
#include <qubus/IR/variable_declaration.hpp>
#include <qubus/IR/variable_ref_expr.hpp>

#include <qubus/util/assert.hpp>
#include <qubus/util/unreachable.hpp>

#include <boost/optional.hpp>
#include <boost/range/adaptor/indirected.hpp>

#include <functional>
#include <memory>
#include <tuple>
#include <vector>

namespace qubus
{
class access
{
public:
    explicit access(const access_expr& access_);

    access(const variable_ref_expr& direct_access_,
           std::vector<std::reference_wrapper<const access_qualifier_expr>> qualifiers_);

    const variable_ref_expr& base() const
    {
        return direct_access_.get();
    }

    const variable_declaration& variable() const
    {
        return base().declaration();
    }

    bool is_qualified() const
    {
        return !qualifiers_.empty();
    }

    decltype(auto) qualifiers() const
    {
        return qualifiers_;
    }

    const expression& location() const;

private:
    explicit access(std::tuple<std::reference_wrapper<const variable_ref_expr>,
                               std::vector<std::reference_wrapper<const access_qualifier_expr>>>
                        data_);

    std::reference_wrapper<const variable_ref_expr> direct_access_;
    std::vector<std::reference_wrapper<const access_qualifier_expr>> qualifiers_;

    std::reference_wrapper<const expression> location_;
};

class access_set_node;

enum class access_kind
{
    external,
    all
};

class access_set
{
public:
    explicit access_set(const access_set_node& root_, access_kind kind_);

    const expression& location() const;

    std::vector<access> get_read_accesses() const;
    std::vector<access> get_write_accesses() const;
private:
    const access_set_node* root_;
    access_kind kind_;
};

class variable_access_index;

class variable_access_analyis_result
{
public:
    explicit variable_access_analyis_result(std::unique_ptr<variable_access_index> access_index_);

    ~variable_access_analyis_result();

    variable_access_analyis_result(const variable_access_analyis_result&) = delete;
    variable_access_analyis_result& operator=(const variable_access_analyis_result&) = delete;

    variable_access_analyis_result(variable_access_analyis_result&&);
    variable_access_analyis_result& operator=(variable_access_analyis_result&&);

    access_set query_accesses_for_location(const expression& location, access_kind kind = access_kind::external) const;

private:
    std::unique_ptr<variable_access_index> access_index_;
};

class variable_access_analysis
{
public:
    using result_type = variable_access_analyis_result;

    variable_access_analyis_result run(const expression& root, analysis_manager& manager,
                                       pass_resource_manager& resource_manager) const;

    std::vector<analysis_id> required_analyses() const;
};
}

#endif

max_stars_repo_name: qubusproject/Qubus

max_issues_repo_name: qubusproject/Qubus

max_forks_repo_name: qubusproject/Qubus


text: #include <boost/type_traits/promote.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
//display kinect depth in real-time
//#define INFO
#define TIMER
#define _USE_MATH_DEFINES
#include <GL/glew.h>

#include <cuda_gl_interop.h>
#include <cuda_runtime_api.h>

#ifdef __gnu_linux__
#include <sys/types.h>
#include <sys/stat.h>
#elif _WIN32
#include <direct.h>
#else
#error "OS not supported!"
#endif
#include <iostream>
#include <string>
#include <vector>

#include <boost/scoped_ptr.hpp>
#include <boost/filesystem.hpp>

#include <opencv2/core.hpp>
#include <opencv2/cudaarithm.hpp>

#include <Eigen/Dense>
//camera calibration from a sequence of images
#include <opencv2/cudaarithm.hpp>
#include <OpenNI.h>
#include "Kinect.h"
#include "GLUtil.hpp"
#include <map>
#include "Camera.h"
#include "VideoSourceKinect.hpp"

//Qt
#include <QGLViewer/qglviewer.h>
#include "Data4Viewer.h"
#include "DataLive.h"

using namespace std;
using namespace cv;
using namespace Eigen;
using namespace qglviewer;
DataLive::DataLive()
:Data4Viewer(){
	_bRepeat = false;// repeatedly play the sequence
	_nStatus = 01;//1 restart; 2 //recording continue 3://pause 4://dump
	_nMethodIdx = 0;
}

void DataLive::loadFromYml(){
	_uResolution = 0;
	_Cw = Vector3d(1,1,1);
	_cam_param_path = string("..\\data\\Xtion");
}

void DataLive::reset(){
	//for testing different oni files
	_nStatus = 9;
	_pGL.reset();
	_pGL.reset( new btl::gl_util::CGLUtil(_uResolution,_uPyrHeight) );
	_pGL->init();
	_pGL->constructVBOsPBOs();
	_pKinect.reset();

	_pKinect.reset( new btl::kinect::VideoSourceKinect(_uResolution,_uPyrHeight,true,_Cw,_cam_param_path) );
	using namespace btl::kinect;
	_pKinect->initKinect();

	int nn = 0;
	bool bIsSuccessful = false;
	while (!bIsSuccessful&&nn < 20){
		bIsSuccessful = _pKinect->getNextFrame(&_nStatus);
		nn++;
	}

	return;
}

void DataLive::updatePF(){
	//int64 A = getTickCount();
	using btl::kinect::VideoSourceKinect;

	//load data from video source and model
	if( !_pKinect->getNextFrame(&_nStatus) ) return;
	return;
}

max_stars_repo_name: ShudaLi/HDRFusion

max_issues_repo_name: etudemin/HDRFusion

max_forks_repo_name: etudemin/HDRFusion


text:
#include <Eigen/StdVector>

#include <pcl/kdtree/kdtree_flann.h>
#include <week_scanmatching/icp/icp.h>
#include <Eigen/Core>

namespace scanmatcher
{
Result ICP::scanmatch(const pcl::PointCloud<pcl::PointXYZ>& input, const pcl::PointCloud<pcl::PointXYZ>& target,
                      const Eigen::Isometry3d& prediction)
{
  // Transformation is sR(p_i) + t
  Eigen::Isometry3d total_transform = Eigen::Isometry3d::Identity();
  double error = std::numeric_limits<double>::infinity();

  // TODO(Oswin) Parametrize this
  int max_iterations = 500;
  double threshold = 1e-5;
  double correspondance_outlier_threshold = 0.5;

  int num_input = input.points.size();

  Eigen::Matrix3Xd aligned_input(3, num_input);
  for (int i = 0; i < num_input; i++)
  {
    aligned_input.col(i) = input[i].getVector3fMap().cast<double>();
  }

  Eigen::Matrix3Xd target_corresp(3, num_input);

  // Construct KD tree for target for finding closest points
  pcl::KdTreeFLANN<pcl::PointXYZ> kdtree;
  pcl::PointCloud<pcl::PointXYZ>::Ptr target_ptr(new pcl::PointCloud<pcl::PointXYZ>);
  *target_ptr = target;
  kdtree.setInputCloud(target_ptr);

  for (int i = 0; i < max_iterations; i++)
  {
    // TODO(Oswin) Make this a KD tree
    std::vector<int> inlier_indices{};
    for (int j = 0; j < num_input; j++)
    {
      pcl::PointXYZ pcl_point;
      pcl_point.getVector3fMap() = aligned_input.col(j).cast<float>();
      std::vector<int> closest_idx;
      std::vector<float> distance;
      kdtree.nearestKSearch(pcl_point, 1, closest_idx, distance);
      auto closest_point = target[closest_idx.front()];
      target_corresp.col(j) = closest_point.getVector3fMap().cast<double>();

      if (std::sqrt(distance.front()) < correspondance_outlier_threshold)
      {
        inlier_indices.emplace_back(j);
      }
    }

    int num_inliers = inlier_indices.size();
    if (num_inliers < 4)
    {
      return { Eigen::Affine3d::Identity(), std::numeric_limits<double>::infinity() };
    }
    Eigen::Matrix3Xd inlier_input(3, num_inliers);
    Eigen::Matrix3Xd inlier_corresp(3, num_inliers);

    for (int idx = 0; idx < num_inliers; idx++)
    {
      int inlier_index = inlier_indices[idx];
      inlier_input.col(idx) = aligned_input.col(inlier_index);
      inlier_corresp.col(idx) = target_corresp.col(inlier_index);
    }

    Eigen::VectorXd weights = Eigen::VectorXd::Ones(num_inliers);
    Eigen::Isometry3d transform = getRigidTransform(weights, inlier_input, inlier_corresp);
    total_transform = transform * total_transform;

    error = 0.0;
    for (int j = 0; j < num_input; j++)
    {
      aligned_input.col(j) = transform * aligned_input.col(j);
      error += (target_corresp.col(j) - aligned_input.col(j)).squaredNorm();
    }
    error /= num_input;

    if (error < threshold)
    {
      break;
    }
  }

  Eigen::Affine3d affine_transform{ total_transform };
  return { affine_transform, error };
}

Eigen::Isometry3d ICP::getRigidTransform(const Eigen::VectorXd& weights, const Eigen::Matrix3Xd& input,
                                         const Eigen::Matrix3Xd& target) const
{
  const int dims = input.cols();

  // 1: Compute weighted centroids of input and target
  const double weights_sum_inverse = 1.0 / weights.sum();
  const Eigen::Vector3d input_centroid =
      (input.array().rowwise() * weights.array().transpose()).rowwise().sum() * weights_sum_inverse;
  const Eigen::Vector3d target_centroid =
      (target.array().rowwise() * weights.array().transpose()).rowwise().sum() * weights_sum_inverse;

  // 2: Subtract centroids from input and target
  const Eigen::Matrix3Xd input_prime = input.colwise() - input_centroid;
  const Eigen::Matrix3Xd target_prime = target.colwise() - target_centroid;

  // 3: Compute S = X W Y^T
  const Eigen::MatrixXd s = target_prime * weights.asDiagonal() * input_prime.transpose();
  const Eigen::JacobiSVD<Eigen::MatrixXd> svd(s, Eigen::ComputeThinU | Eigen::ComputeThinV);
  Eigen::Matrix3d rotation_matrix = svd.matrixV() * svd.matrixU().transpose();

  if (rotation_matrix.determinant() < 0)
  {
    Eigen::MatrixXd altered_v = svd.matrixV();
    altered_v.col(dims) *= -1;
    rotation_matrix = altered_v * svd.matrixU().transpose();
  }

  Eigen::Isometry3d transform{ rotation_matrix.transpose() };
  transform.translation() = target_centroid - rotation_matrix * input_centroid;

  return transform;
}
}  // namespace scanmatcher

max_issues_repo_name: RoboJackets/igvc-training

max_forks_repo_name: RoboJackets/igvc-training


text:
#include "kafka/KafkaProducer.h"

#include <boost/algorithm/string.hpp>
#include <boost/program_options.hpp>

#include <iostream>
#include <string>
#include <vector>

namespace Kafka = KAFKA_API;

struct Arguments
{
    std::vector<std::string>   brokerList;
    std::string                topic;
    Optional<Kafka::Partition> partition;
    std::map<std::string, std::string> props;
};

std::unique_ptr<Arguments> ParseArguments(int argc, char **argv)
{
    auto args = std::make_unique<Arguments>();
    std::vector<std::string> propList;
    int partition = -1;

    namespace po = boost::program_options;
    po::options_description desc("Options description");
    desc.add_options()
            ("help,h",
                "Print usage information.")
            ("broker-list",
                po::value<std::vector<std::string>>(&args->brokerList)->multitoken()->required(),
                "REQUIRED: The server(s) to connect to.")
            ("topic",
                po::value<std::string>(&args->topic)->required(),
                "REQUIRED: The topic to publish to.")
            ("partition",
                po::value<int>(&partition),
                "The partition to publish to.")
            ("props",
                po::value<std::vector<std::string>>(&propList)->multitoken(),
                "Kafka producer properties in key=value format.");

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

    if (vm.count("help") || argc == 1)
    {
        std::cout << "Read data from the standard input and send it to the given Kafka topic" << std::endl;
        std::cout << "    (with librdkafka v" << Kafka::Utility::getLibRdKafkaVersion() << ")" << std::endl;
        std::cout << desc << std::endl;
        return nullptr;
    }

    po::notify(vm);

    if (partition >= 0)
    {
        args->partition = partition;
    }

    for (const auto& prop: propList)
    {
        std::vector<std::string> keyValue;
        boost::algorithm::split(keyValue, prop, boost::is_any_of("="));
        if (keyValue.size() != 2)
        {
            throw std::invalid_argument("Unexpected --props value! Expected key=value format");
        }
        args->props[keyValue[0]] = keyValue[1];
    }

    return args;
}

int main (int argc, char **argv)
{
    // Parse input arguments
    std::unique_ptr<Arguments> args;
    try
    {
        args = ParseArguments(argc, argv);
    }
    catch (const std::exception& e)
    {
        std::cout << e.what() << std::endl;
        return EXIT_FAILURE;
    }
    if (!args) // Only for "help"
    {
        return EXIT_SUCCESS;
    }

    // Prepare consumer properties
    Kafka::ProducerConfig props;
    props.put(Kafka::ProducerConfig::BOOTSTRAP_SERVERS, boost::algorithm::join(args->brokerList, ","));
    // Get client id
    std::ostringstream oss;
    oss << "producer-" << std::this_thread::get_id();
    props.put(Kafka::ProducerConfig::CLIENT_ID, oss.str());
    // For other properties user assigned
    for (const auto& prop: args->props)
    {
        props.put(prop.first, prop.second);
    }

    // Create a sync-send producer
    Kafka::KafkaClient::setGlobalLogger(Kafka::Logger());
    Kafka::KafkaProducer producer(props);

    auto startPromptLine = []() { std::cout << "> "; };

    // Keep reading lines and send it towards kafka cluster
    startPromptLine();

    std::string line;
    while (std::getline(std::cin, line))
    {
        Kafka::Key   key;
        Kafka::Value value(line.c_str(), line.size());
        Kafka::ProducerRecord record =
            (args->partition ? Kafka::ProducerRecord(args->topic, *args->partition, key, value) : Kafka::ProducerRecord(args->topic, key, value));
        try
        {
            std::cout << "Current Local Time [" << Kafka::Utility::getCurrentTime() << "]" << std::endl;

            // Note: might throw exceptions if with unknown topic, unknown partition, invalid message length, etc.
            auto metadata = producer.syncSend(record);

            std::cout << "Just Sent Key[" << metadata.keySize()   << " B]/Value["  << metadata.valueSize() << " B]"
                << " ==> " << metadata.topic() << "-" << std::to_string(metadata.partition()) << "@" <<  (metadata.offset() ? std::to_string(*metadata.offset()) : "NA")
                << ", " << metadata.timestamp().toString() << ", " << metadata.persistedStatusString() << std::endl;
        }
        catch (const Kafka::KafkaException& e)
        {
            std::cerr << "Exception thrown by producer: " << e.what() << std::endl;
        }

        std::cout << "--------------------" << std::endl;
        startPromptLine();
    }

    return EXIT_SUCCESS;
}

max_stars_repo_name: JorgeFMorais/modern-cpp-kafka

max_issues_repo_name: JorgeFMorais/modern-cpp-kafka

max_forks_repo_name: JorgeFMorais/modern-cpp-kafka


text:
//  Copyright (c) 2019 AUTHORS
//
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include "octotiger/config.hpp"

#include "octotiger/container_device.hpp"
#include "octotiger/defs.hpp"
#include "octotiger/diagnostics.hpp"
#include "octotiger/future.hpp"
#include "octotiger/node_client.hpp"
#include "octotiger/node_registry.hpp"
#include "octotiger/node_server.hpp"
#include "octotiger/options.hpp"
#include "octotiger/profiler.hpp"
#include "octotiger/taylor.hpp"

#include <hpx/include/lcos.hpp>
#include <hpx/include/run_as.hpp>
#include <hpx/collectives/broadcast.hpp>

#include <boost/iostreams/stream.hpp>

#include <algorithm>
#include <array>
#include <chrono>
#include <fstream>
#include <vector>

using amr_error_action_type = node_server::amr_error_action;
HPX_REGISTER_ACTION(amr_error_action_type);

future<std::pair<real, real>> node_client::amr_error() const {
	return hpx::async<typename node_server::amr_error_action>(get_unmanaged_gid());
}

std::pair<real, real> node_server::amr_error() {
	std::vector<hpx::future<std::pair<real, real>>> kfuts;
	auto sum = std::make_pair(0.0, 0.0);
	if (is_refined) {
		for (int i = 0; i < NCHILD; i++) {
			kfuts.push_back(children[i].amr_error());
		}
		hpx::wait_all(kfuts);
		for (int i = 0; i < NCHILD; i++) {
			auto tmp = kfuts[i].get();
			sum.first += tmp.first;
			sum.second += tmp.second;
		}
	} else {
		sum = grid_ptr->amr_error();
	}
	return sum;
}

using regrid_gather_action_type = node_server::regrid_gather_action;
HPX_REGISTER_ACTION(regrid_gather_action_type);

future<node_count_type> node_client::regrid_gather(bool rb) const {
	return hpx::async<typename node_server::regrid_gather_action>(get_unmanaged_gid(), rb);
}

node_count_type node_server::regrid_gather(bool rebalance_only) {
	node_registry::delete_(my_location);
	node_count_type count;
	count.total = 1;
	count.leaf = is_refined ? 0 : 1;
	std::vector<hpx::future<void>> kfuts;
	if (is_refined) {
		if (!rebalance_only) {
			/* Turning refinement off */
			if (refinement_flag == 0) {
				for (int i = 0; i < NCHILD; i++) {
					kfuts.push_back(children[i].kill());
				}
				std::fill_n(children.begin(), NCHILD, node_client());
				is_refined = false;
			}
		}

		if (is_refined) {
			std::array<future<node_count_type>, NCHILD> futs;
			integer index = 0;
			for (auto &child : children) {
				futs[index++] = child.regrid_gather(rebalance_only);
			}
			auto futi = futs.begin();
			for (auto const &ci : geo::octant::full_set()) {
				const auto child_cnt = futi->get();
				++futi;
				child_descendant_count[ci] = child_cnt.total;
				count.leaf += child_cnt.leaf;
				count.total += child_cnt.total;
			}
		} else {
			count.leaf = 1;
			for (auto const &ci : geo::octant::full_set()) {
				child_descendant_count[ci] = 0;
			}
		}
	} else if (!rebalance_only) {
		if (refinement_flag != 0) {
			refinement_flag = 0;
			count.total += NCHILD;
			count.leaf += NCHILD - 1;

			/* Turning refinement on*/
			is_refined = true;

			for (auto &ci : geo::octant::full_set()) {
				child_descendant_count[ci] = 1;

			}
		}
	}
	grid_ptr->set_leaf(!is_refined);
	hpx::wait_all(kfuts);
	return count;
}

future<hpx::id_type> node_server::create_child(hpx::id_type const &locality, integer ci) {
	return hpx::async(hpx::util::annotated_function([ci, this](hpx::id_type const locality) {

		return hpx::new_<node_server>(locality, my_location.get_child(ci), me, current_time, rotational_time, step_num, hcycle, rcycle, gcycle).then([this, ci](future<hpx::id_type> &&child_idf) {
		hpx::id_type child_id = child_idf.get();
		node_client child = child_id;
		{
			std::array<integer, NDIM> lb = {2 * H_BW, 2 * H_BW, 2 * H_BW};
			std::array<integer, NDIM> ub;
			lb[XDIM] += (1 & (ci >> 0)) * (INX);
			lb[YDIM] += (1 & (ci >> 1)) * (INX);
			lb[ZDIM] += (1 & (ci >> 2)) * (INX);
			for (integer d = 0; d != NDIM; ++d) {
				ub[d] = lb[d] + (INX);
			}
			std::vector<real> outflows(opts().n_fields, ZERO);
			if (ci == 0) {
				outflows = grid_ptr->get_outflows_raw();
			}
			if (current_time > ZERO || opts().restart_filename != "") {
				std::vector<real> prolong;
				{
					std::unique_lock < hpx::lcos::local::spinlock > lk(prolong_mtx);
					prolong = grid_ptr->get_prolong(lb, ub);
				}
				GET(child.set_grid(std::move(prolong), std::move(outflows)));
			}
		}
		if (opts().radiation) {
			std::array<integer, NDIM> lb = {2 * R_BW, 2 * R_BW, 2 * R_BW};
			std::array<integer, NDIM> ub;
			lb[XDIM] += (1 & (ci >> 0)) * (INX);
			lb[YDIM] += (1 & (ci >> 1)) * (INX);
			lb[ZDIM] += (1 & (ci >> 2)) * (INX);
			for (integer d = 0; d != NDIM; ++d) {
				ub[d] = lb[d] + (INX);
			}
			/*	std::vector<real> outflows(NF, ZERO);
			 if (ci == 0) {
			 outflows = grid_ptr->get_outflows();
			 }*/
			if (current_time > ZERO) {
				std::vector<real> prolong;
				{
					std::unique_lock < hpx::lcos::local::spinlock > lk(prolong_mtx);
					prolong = rad_grid_ptr->get_prolong(lb, ub);
				}
				child.set_rad_grid(std::move(prolong)/*, std::move(outflows)*/).get();
			}
		}
		return child_id;
	});}, "node_server::create_child::lambda"), locality);
}

using regrid_scatter_action_type = node_server::regrid_scatter_action;
HPX_REGISTER_ACTION(regrid_scatter_action_type);

future<void> node_client::regrid_scatter(integer a, integer b) const {
	return hpx::async<typename node_server::regrid_scatter_action>(get_unmanaged_gid(), a, b);
}

void node_server::regrid_scatter(integer a_, integer total) {
	position = a_;
	refinement_flag = 0;
	std::array<future<void>, geo::octant::count()> futs;
	if (is_refined) {
		integer a = a_;
		++a;
		integer index = 0;
		for (auto &ci : geo::octant::full_set()) {
			const integer loc_index = a * options::all_localities.size() / total;
			const auto child_loc = options::all_localities[loc_index];
			if (children[ci].empty()) {
				futs[index++] = create_child(child_loc, ci).then([this, ci, a, total](future<hpx::id_type> &&child) {
					children[ci] = GET(child);
					GET(children[ci].regrid_scatter(a, total));
				});
			} else {
				const hpx::id_type id = children[ci].get_gid();
				integer current_child_id = hpx::naming::get_locality_id_from_gid(id.get_gid());
				auto current_child_loc = options::all_localities[current_child_id];
				if (child_loc != current_child_loc) {
					futs[index++] = children[ci].copy_to_locality(child_loc).then([this, ci, a, total](future<hpx::id_type> &&child) {
						children[ci] = GET(child);
						GET(children[ci].regrid_scatter(a, total));
					});
				} else {
					futs[index++] = children[ci].regrid_scatter(a, total);
				}
			}
			a += child_descendant_count[ci];
		}
	}
	if (is_refined) {
		for (auto &f : futs) {
			GET(f);
		}
	}
	clear_family();
}

node_count_type node_server::regrid(const hpx::id_type &root_gid, real omega, real new_floor, bool rb, bool grav_energy_comp) {
	timings::scope ts(timings_, timings::time_regrid);
	hpx::util::high_resolution_timer timer;
	assert(grid_ptr != nullptr);
	print("-----------------------------------------------\n");
	if (!rb) {
		print("checking for refinement\n");
		check_for_refinement(omega, new_floor);
	} else {
		node_registry::clear();
	}
	print("regridding\n");
	real tstart = timer.elapsed();
	auto a = regrid_gather(rb);
	real tstop = timer.elapsed();
	print("Regridded tree in %f seconds\n", real(tstop - tstart));
	print("rebalancing %i nodes with %i leaves\n", int(a.total), int(a.leaf));
	tstart = timer.elapsed();
	regrid_scatter(0, a.total);
	tstop = timer.elapsed();
	print("Rebalanced tree in %f seconds\n", real(tstop - tstart));
	assert(grid_ptr != nullptr);
	tstart = timer.elapsed();
	print("forming tree connections\n");
	a.amr_bnd = form_tree(hpx::unmanaged(root_gid));
	print("%i amr boundaries\n", a.amr_bnd);
	tstop = timer.elapsed();
	print("Formed tree in %f seconds\n", real(tstop - tstart));
	print("solving gravity\n");
	solve_gravity(grav_energy_comp, false);
	double elapsed = timer.elapsed();
	print("regrid done in %f seconds\n---------------------------------------\n", elapsed);
	return a;
}

using set_aunt_action_type = node_server::set_aunt_action;
HPX_REGISTER_ACTION(set_aunt_action_type);

future<void> node_client::set_aunt(const hpx::id_type &aunt, const geo::face &f) const {
	return hpx::async<typename node_server::set_aunt_action>(get_unmanaged_gid(), aunt, f);
}

void node_server::set_aunt(const hpx::id_type &aunt, const geo::face &face) {
	if (aunts[face].get_gid() != hpx::invalid_id) {
		print("AUNT ALREADY SET\n");
		abort();
	}
	aunts[face] = aunt;
}

using set_grid_action_type = node_server::set_grid_action;
HPX_REGISTER_ACTION(set_grid_action_type);

future<void> node_client::set_grid(std::vector<real> &&g, std::vector<real> &&o) const {
	return hpx::async<typename node_server::set_grid_action>(get_unmanaged_gid(), std::move(g), std::move(o));
}

void node_server::set_grid(const std::vector<real> &data, std::vector<real> &&outflows) {
	grid_ptr->set_prolong(data, std::move(outflows));
}

using solve_gravity_action_type = node_server::solve_gravity_action;
HPX_REGISTER_ACTION(solve_gravity_action_type);

future<void> node_client::solve_gravity(bool ene, bool aonly) const {
	return hpx::async<typename node_server::solve_gravity_action>(get_unmanaged_gid(), ene, aonly);
}

void node_server::solve_gravity(bool ene, bool aonly) {
	if (!opts().gravity) {
		return;
	}
	std::array<future<void>, NCHILD> child_futs;
	if (is_refined) {
		integer index = 0;
		;
		for (auto &child : children) {
			child_futs[index++] = child.solve_gravity(ene, aonly);
		}
	}
	compute_fmm(RHO, ene, aonly);
	if (is_refined) {
		//	wait_all_and_propagate_exceptions(child_futs);
		for (auto &f : child_futs) {
			GET(f);
		}
	}
}


text:
/*
 * Copyright (c) 2009-2016, Albertas Vyšniauskas
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 *     * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "ImportExport.h"
#include "ColorObject.h"
#include "ColorList.h"
#include "FileFormat.h"
#include "Converters.h"
#include "Converter.h"
#include "Endian.h"
#include "I18N.h"
#include "StringUtils.h"
#include "HtmlUtils.h"
#include "GlobalState.h"
#include "DynvHelpers.h"
#include "version/Version.h"
#include "parser/TextFile.h"
#include <glib.h>
#include <fstream>
#include <string>
#include <sstream>
#include <boost/math/special_functions/round.hpp>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
using namespace std;

static bool getOrderedColors(ColorList *color_list, vector<ColorObject*> &ordered)
{
	color_list_get_positions(color_list);
	size_t max_index = 0;
	bool index_set = false;
	for (auto color: color_list->colors){
		if (color->isPositionSet()){
			if (!index_set){
				max_index = color->getPosition();
				index_set = true;
			}else if (color->getPosition() > max_index){
				max_index = color->getPosition();
			}
		}
	}
	if (!index_set){
		return false;
	}else{
		ordered.resize(max_index + 1);
		for (auto color: color_list->colors){
			if (color->isPositionSet()){
				ordered[color->getPosition()] = color;
			}
		}
		return true;
	}
}
ImportExport::ImportExport(ColorList *color_list, const char* filename, GlobalState *gs):
	m_color_list(color_list),
	m_converter(nullptr),
	m_converters(nullptr),
	m_filename(filename),
	m_item_size(ItemSize::medium),
	m_background(Background::none),
	m_gs(gs),
	m_include_color_names(true),
	m_last_error(Error::none)
{
}
void ImportExport::fixFileExtension(const char *selected_filter)
{
	using namespace boost::filesystem;
	if (selected_filter && selected_filter[0] == '*'){
		string extension = path(m_filename).extension().string();
		bool append = false;
		if (extension.length() == 0){
			append = true;
		}else{
			if (getFileTypeByExtension(extension.c_str()) == FileType::unknown)
				append = true;
		}
		if (append){
			size_t length = m_filename.length();
			m_filename += &selected_filter[1];
			size_t additional_extension = m_filename.find_first_of(',', length);
			if (additional_extension != string::npos){
				m_filename = m_filename.substr(0, additional_extension);
			}
		}
	}
}
void ImportExport::setConverter(Converter *converter)
{
	m_converter = converter;
}
void ImportExport::setConverters(Converters *converters)
{
	m_converters = converters;
}
void ImportExport::setItemSize(ItemSize item_size)
{
	m_item_size = item_size;
}
void ImportExport::setItemSize(const char *item_size)
{
	string v(item_size);
	if (v == "small")
		m_item_size = ItemSize::small;
	else if (v == "medium")
		m_item_size = ItemSize::medium;
	else if (v == "big")
		m_item_size = ItemSize::big;
	else if (v == "controllable")
		m_item_size = ItemSize::controllable;
	else
		m_item_size = ItemSize::medium;
}
void ImportExport::setBackground(Background background)
{
	m_background = background;
}
void ImportExport::setBackground(const char *background)
{
	string v(background);
	if (v == "none")
		m_background = Background::none;
	else if (v == "white")
		m_background = Background::white;
	else if (v == "gray")
		m_background = Background::gray;
	else if (v == "black")
		m_background = Background::black;
	else if (v == "first_color")
		m_background = Background::first_color;
	else if (v == "last_color")
		m_background = Background::last_color;
	else if (v == "controllable")
		m_background = Background::controllable;
	else
		m_background = Background::none;
}
void ImportExport::setIncludeColorNames(bool include_color_names)
{
	m_include_color_names = include_color_names;
}
static void gplColor(ColorObject* color_object, ostream &stream)
{
	using boost::math::iround;
	Color color = color_object->getColor();
	stream
		<< iround(color.rgb.red * 255) << "\t"
		<< iround(color.rgb.green * 255) << "\t"
		<< iround(color.rgb.blue * 255) << "\t" << color_object->getName() << endl;
}
bool ImportExport::exportGPL()
{
	ofstream f(m_filename, ios::out | ios::trunc);
	if (!f.is_open()){
		m_last_error = Error::could_not_open_file;
		return false;
	}
	boost::filesystem::path path(m_filename);
	f << "GIMP Palette" << endl;
	f << "Name: " << path.filename().string() << endl;
	f << "Columns: 1" << endl;
	f << "#" << endl;
	vector<ColorObject*> ordered;
	getOrderedColors(m_color_list, ordered);
	for (auto color: ordered){
		gplColor(color, f);
		if (!f.good()){
			f.close();
			m_last_error = Error::file_write_error;
			return false;
		}
	}
	f.close();
	return true;
}
bool ImportExport::importGPL()
{
	ifstream f(m_filename, ios::in);
	if (!f.is_open()){
		m_last_error = Error::could_not_open_file;
		return false;
	}
	string line;
	getline(f, line);
	if (f.good() && line != "GIMP Palette"){
		f.close();
		m_last_error = Error::file_read_error;
		return false;
	}
	do{
		getline(f, line);
	}while (f.good() && ((line.size() < 1) || (((line[0] > '9') || (line[0] < '0')) && line[0] != ' ')));
	int r, g, b;
	Color c;
	ColorObject* color_object;
	string strip_chars = " \t";
	for(;;){
		if (!f.good()) break;
		stripLeadingTrailingChars(line, strip_chars);
		if (line.length() > 0 && line[0] == '#'){ // skip comment lines
			getline(f, line);
			continue;
		}
		stringstream ss(line);
		ss >> r >> g >> b;
		getline(ss, line);
		if (!f.good()) line = "";
		c.rgb.red = r / 255.0;
		c.rgb.green = g / 255.0;
		c.rgb.blue = b / 255.0;
		color_object = color_list_new_color_object(m_color_list, &c);
		stripLeadingTrailingChars(line, strip_chars);
		color_object->setName(line);
		color_list_add_color_object(m_color_list, color_object, true);
		color_object->release();
		getline(f, line);
	}
	if (!f.eof()) {
		f.close();
		m_last_error = Error::file_read_error;
		return false;
	}
	f.close();
	return true;
}
bool ImportExport::importGPA()
{
	return palette_file_load(m_filename.c_str(), m_color_list) == 0;
}
bool ImportExport::exportGPA()
{
	return palette_file_save(m_filename.c_str(), m_color_list) == 0;
}
bool ImportExport::exportTXT()
{
	ofstream f(m_filename.c_str(), ios::out | ios::trunc);
	if (!f.is_open()){
		m_last_error = Error::could_not_open_file;
		return false;
	}
	vector<ColorObject*> ordered;
	getOrderedColors(m_color_list, ordered);
	ConverterSerializePosition position(ordered.size());
	for (auto color: ordered){
		string line = m_converter->serialize(color, position);
		f << line << endl;
		position.incrementIndex();
		if (position.index() + 1 == position.count()){
			position.last(true);
		}
		if (position.first())
			position.first(false);
		if (!f.good()){
			f.close();
			m_last_error = Error::file_write_error;
			return false;
		}
	}
	f.close();
	return true;
}
bool ImportExport::importTXT()
{
	ifstream f(m_filename.c_str(), ios::in);
	if (!f.is_open()){
		m_last_error = Error::could_not_open_file;
		return false;
	}
	ColorObject *color_object;
	Color dummy_color;
	multimap<float, ColorObject*, greater<float>> valid_converters;
	string line;
	string strip_chars = " \t";
	bool imported = false;
	for(;;){
		getline(f, line);
		stripLeadingTrailingChars(line, strip_chars);
		if (!line.empty()){
			for (auto &converter: m_converters->allPaste()){
				if (!converter->hasDeserialize())
					continue;
				color_object = color_list_new_color_object(m_color_list, &dummy_color);
				float quality;
				if (converter->deserialize(line.c_str(), color_object, quality)){
					if (quality > 0){
						valid_converters.insert(make_pair(quality, color_object));
					}else{
						color_object->release();
					}
				}else{
					color_object->release();
				}
			}
			bool first = true;
			for (auto result: valid_converters){
				if (first){
					first = false;
					color_list_add_color_object(m_color_list, result.second, true);
					imported = true;
				}
				result.second->release();
			}
			valid_converters.clear();
		}
		if (!f.good()) {
			if (f.eof()) break;
			f.close();
			m_last_error = Error::file_read_error;
			return false;
		}
	}
	f.close();
	if (!imported){
		m_last_error = Error::no_colors_imported;
	}
	return imported;
}
static void cssColor(ColorObject* color_object, ostream &stream)
{
	Color color, hsl;
	color = color_object->getColor();
	color_rgb_to_hsl(&color, &hsl);
	stream << " * " << color_object->getName()
		<< ": " << HtmlHEX{&color}
		<< ", " << HtmlRGB{&color}
		<< ", " << HtmlHSL{&color}
		<< endl;
}
bool ImportExport::exportCSS()
{
	ofstream f(m_filename.c_str(), ios::out | ios::trunc);
	if (!f.is_open()){
		m_last_error = Error::could_not_open_file;
		return false;
	}
	f << "/**" << endl << " * Generated by Gpick " << gpick_build_version << endl;
	vector<ColorObject*> ordered;
	getOrderedColors(m_color_list, ordered);
	for (auto color: ordered){
		cssColor(color, f);
		if (!f.good()){
			f.close();
			m_last_error = Error::file_write_error;
			return false;
		}
	}
	f << " */" << endl;
	if (!f.good()){
		f.close();
		m_last_error = Error::file_write_error;
		return false;
	}
	f.close();
	return true;
}
static void htmlColor(ColorObject* color_object, bool include_color_name, ostream &stream)
{
	Color color, text_color;
	color = color_object->getColor();
	color_get_contrasting(&color, &text_color);
	stream << "<div style=\"background-color:" << HtmlRGB{&color} << "; color:" << HtmlRGB{&text_color} << "\">";
	if (include_color_name){
		string name = color_object->getName();
		escapeHtmlInplace(name);
		if (!name.empty())
			stream << name << ":
";
	}
	stream << "" << HtmlHEX{&color} << "" << "
";
}
static string getHtmlColor(ColorObject* color_object)
{
	Color color = color_object->getColor();
	stringstream ss;
	ss << HtmlRGB{&color};
	return ss.str();
}
bool ImportExport::exportHTML()
{
	ofstream f(m_filename.c_str(), ios::out | ios::trunc);
	if (!f.is_open()){
		m_last_error = Error::could_not_open_file;
		return false;
	}
	boost::filesystem::path path(m_filename);
	vector<ColorObject*> ordered;
	getOrderedColors(m_color_list, ordered);
	int item_size = 64;
	switch (m_item_size){
		case ItemSize::small:
			item_size = 32;
			break;
		case ItemSize::medium:
			item_size = 64;
			break;
		case ItemSize::big:
			item_size = 96;
			break;
		case ItemSize::controllable:
			break;
	}
	string background = "";
	switch (m_background){
		case Background::none:
			break;
		case Background::white:
			background = "background-color:white;";
			break;
		case Background::gray:
			background = "background-color:gray;";
			break;
		case Background::black:
			background = "background-color:black;";
			break;
		case Background::first_color:
			if (!ordered.empty())
				background = "background-color:" + getHtmlColor(ordered.front()) + ";";
			break;
		case Background::last_color:
			if (!ordered.empty())
				background = "background-color:" + getHtmlColor(ordered.back()) + ";";
			break;
		case Background::controllable:
			break;
	}
	f << "<!DOCTYPE html><meta charset=\"utf-8\"><title>"
		<< path.filename().string() << "</title>" << endl
		<< "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">" << endl
		<< ""
		<< "" << endl
		<< "" << endl;
	if (m_item_size == ItemSize::controllable || m_background == Background::controllable){
		f << "<form>" << endl;
		if (m_item_size == ItemSize::controllable){
			f << "
" << _("Item size") << ":<input type=\"range\" id=\"item_size\" min=\"16\" max=\"128\" value=\"64\" oninput=\"var elements = document.querySelectorAll('div#colors div'); for (var i = 0; i < elements.length; i++){ elements[i].style.width = this.value + 'px'; elements[i].style.height = this.value + 'px'; }\" />" << "
" << endl;
		}
		if (m_background == Background::controllable){
			f << "
" << _("Background color") << ":<input type=\"color\" id=\"background\" oninput=\"document.body.style.backgroundColor = this.value;\" />" << "
" << endl;
		}
		f << "</form>" << endl;
	}
	f << "
" << endl;
	string hex_case = dynv_get_string_wd(m_gs->getSettings(), "gpick.options.hex_case", "upper");
	if (hex_case == "upper"){
		f << uppercase;
	}else{
		f << nouppercase;
	}
	for (auto color: ordered){
		htmlColor(color, m_include_color_names, f);
		if (!f.good()){
			f.close();
			m_last_error = Error::file_write_error;
			return false;
		}
	}
	f << "
" << endl;
	f << "";
	f << "" << endl;
	if (!f.good()){
		f.close();
		m_last_error = Error::file_write_error;
		return false;
	}
	f.close();
	return true;
}

bool ImportExport::exportType(FileType type)
{
	switch (type){
		case FileType::gpa:
			return exportGPA();
		case FileType::gpl:
			return exportGPL();
		case FileType::ase:
			return exportASE();
		case FileType::txt:
			return exportTXT();
		case FileType::mtl:
			return exportMTL();
		case FileType::css:
			return exportCSS();
		case FileType::html:
			return exportHTML();
		case FileType::rgbtxt:
		case FileType::unknown:
			return false;
	}
	return false;
}
static void mtlColor(ColorObject* color_object, ostream &stream)
{
	Color color = color_object->getColor();
	stream << "newmtl " << color_object->getName() << endl;
	stream << "Ns 90.000000" << endl;
	stream << "Ka 0.000000 0.000000 0.000000" << endl;
	stream << "Kd " << color.rgb.red << " " << color.rgb.green << " " << color.rgb.blue << endl;
	stream << "Ks 0.500000 0.500000 0.500000" << endl << endl;
}
bool ImportExport::exportMTL()
{
	ofstream f(m_filename.c_str(), ios::out | ios::trunc);
	if (!f.is_open()){
		m_last_error = Error::could_not_open_file;
		return false;
	}
	vector<ColorObject*> ordered;
	getOrderedColors(m_color_list, ordered);
	for (auto color: ordered){
		mtlColor(color, f);
		if (!f.good()){
			f.close();
			m_last_error = Error::file_write_error;
			return false;
		}
	}
	f.close();
	return true;
}
typedef union FloatInt
{
	float f;
	uint32_t i;
}FloatInt;
static void aseColor(ColorObject* color_object, ostream &stream)
{
	Color color = color_object->getColor();
	string name = color_object->getName();
	glong name_u16_len = 0;
	gunichar2 *name_u16 = g_utf8_to_utf16(name.c_str(), -1, 0, &name_u16_len, 0);
	for (glong i = 0; i < name_u16_len; ++i){
		name_u16[i] = UINT16_TO_BE(name_u16[i]);
	}
	uint16_t color_entry = UINT16_TO_BE(0x0001);
	stream.write((char*)&color_entry, 2);
	int32_t block_size = 2 + (name_u16_len + 1) * 2 + 4 + (3 * 4) + 2; //name length + name (zero terminated and 2 bytes per char wide) + color name + 3 float values + color type
	block_size = UINT32_TO_BE(block_size);
	stream.write((char*)&block_size, 4);
	uint16_t name_length = UINT16_TO_BE(uint16_t(name_u16_len + 1));
	stream.write((char*)&name_length, 2);
	stream.write((char*)name_u16, (name_u16_len + 1) * 2);
	stream << "RGB ";
	FloatInt r, g, b;
	r.f = color.rgb.red;
	g.f = color.rgb.green;
	b.f = color.rgb.blue;
	r.i = UINT32_TO_BE(r.i);
	g.i = UINT32_TO_BE(g.i);
	b.i = UINT32_TO_BE(b.i);
	stream.write((char*)&r, 4);
	stream.write((char*)&g, 4);
	stream.write((char*)&b, 4);
	int16_t color_type = UINT16_TO_BE(0);
	stream.write((char*)&color_type, 2);
	g_free(name_u16);
}
bool ImportExport::exportASE()
{
	ofstream f(m_filename.c_str(), ios::out | ios::trunc | ios::binary);
	if (!f.is_open()){
		m_last_error = Error::could_not_open_file;
		return false;
	}
	f << "ASEF"; //magic header
	uint32_t version = UINT32_TO_BE(0x00010000);
	f.write((char*)&version, 4);
	vector<ColorObject*> ordered;
	getOrderedColors(m_color_list, ordered);
	uint32_t blocks = ordered.size();
	blocks = UINT32_TO_BE(blocks);
	f.write((char*)&blocks, 4);
	for (auto color: ordered){
		aseColor(color, f);
		if (!f.good()){
			f.close();
			m_last_error = Error::file_write_error;
			return false;
		}
	}
	f.close();
	return true;
}
bool ImportExport::importASE()
{
	ifstream f(m_filename.c_str(), ios::binary);
	if (!f.is_open()){
		m_last_error = Error::could_not_open_file;
		return false;
	}
	char magic[4];
	f.read(magic, 4);
	if (memcmp(magic, "ASEF", 4) != 0){
		f.close();
		m_last_error = Error::file_read_error;
		return false;
	}
	uint32_t version;
	f.read((char*)&version, 4);
	version = UINT32_FROM_BE(version);
	uint32_t blocks;
	f.read((char*)&blocks, 4);
	blocks = UINT32_FROM_BE(blocks);
	uint16_t block_type;
	uint32_t block_size;
	int color_supported;
	for (uint32_t i = 0; i < blocks; ++i){
		f.read((char*)&block_type, 2);
		block_type = UINT16_FROM_BE(block_type);
		f.read((char*)&block_size, 4);
		block_size = UINT32_FROM_BE(block_size);
		switch (block_type){
		case 0x0001: //color block
			{
				uint16_t name_length;
				f.read((char*)&name_length, 2);
				name_length = UINT16_FROM_BE(name_length);

				gunichar2 *name_u16 = (gunichar2*)g_malloc(name_length*2);
				f.read((char*)name_u16, name_length*2);
				for (uint32_t j = 0; j < name_length; ++j){
					name_u16[j] = UINT16_FROM_BE(name_u16[j]);
				}
				gchar *name = g_utf16_to_utf8(name_u16, name_length, 0, 0, 0);
				g_free(name_u16);
				Color c;
				char color_space[4];
				f.read(color_space, 4);
				color_supported = 0;
				if (memcmp(color_space, "RGB ", 4) == 0){
					FloatInt rgb[3];
					f.read((char*)&rgb[0], 4);
					f.read((char*)&rgb[1], 4);
					f.read((char*)&rgb[2], 4);
					rgb[0].i = UINT32_FROM_BE(rgb[0].i);
					rgb[1].i = UINT32_FROM_BE(rgb[1].i);
					rgb[2].i = UINT32_FROM_BE(rgb[2].i);
					c.rgb.red = rgb[0].f;
					c.rgb.green = rgb[1].f;
					c.rgb.blue = rgb[2].f;
					color_supported = 1;
				}else if (memcmp(color_space, "CMYK", 4) == 0){
					Color c2;
					FloatInt cmyk[4];
					f.read((char*)&cmyk[0], 4);
					f.read((char*)&cmyk[1], 4);
					f.read((char*)&cmyk[2], 4);
					f.read((char*)&cmyk[3], 4);
					cmyk[0].i = UINT32_FROM_BE(cmyk[0].i);
					cmyk[1].i = UINT32_FROM_BE(cmyk[1].i);
					cmyk[2].i = UINT32_FROM_BE(cmyk[2].i);
					cmyk[3].i = UINT32_FROM_BE(cmyk[3].i);
					c2.cmyk.c = cmyk[0].f;
					c2.cmyk.m = cmyk[1].f;
					c2.cmyk.y = cmyk[2].f;
					c2.cmyk.k = cmyk[3].f;
					color_cmyk_to_rgb(&c2, &c);
					color_supported = 1;
				}else if (memcmp(color_space, "Gray", 4) == 0){
					FloatInt gray;
					f.read((char*)&gray, 4);
					gray.i = UINT32_FROM_BE(gray.i);
					c.rgb.red = c.rgb.green = c.rgb.blue = gray.f;
					color_supported = 1;
				}else if (memcmp(color_space, "LAB ", 4) == 0){
					Color c2;
					FloatInt lab[3];
					f.read((char*)&lab[0], 4);
					f.read((char*)&lab[1], 4);
					f.read((char*)&lab[2], 4);
					lab[0].i = UINT32_FROM_BE(lab[0].i);
					lab[1].i = UINT32_FROM_BE(lab[1].i);
					lab[2].i = UINT32_FROM_BE(lab[2].i);
					c2.lab.L = lab[0].f*100;
					c2.lab.a = lab[1].f;
					c2.lab.b = lab[2].f;
					color_lab_to_rgb_d50(&c2, &c);
					c.rgb.red = clamp_float(c.rgb.red, 0, 1);
					c.rgb.green = clamp_float(c.rgb.green, 0, 1);
					c.rgb.blue = clamp_float(c.rgb.blue, 0, 1);
					color_supported = 1;
				}
				if (color_supported){
					ColorObject* color_object;
					color_object = color_list_new_color_object(m_color_list, &c);
					color_object->setName(name);
					color_list_add_color_object(m_color_list, color_object, true);
					color_object->release();
				}
				uint16_t color_type;
				f.read((char*)&color_type, 2);
				g_free(name);
			}
			break;
		default:
			f.seekg(block_size, ios::cur);
		}
	}
	f.close();
	return true;
}
static string::size_type rfind_first_of_not(string const& str, string::size_type const pos, string const& chars)
{
	auto start = str.rend() - pos - 1;
	auto found = std::find_first_of(start, str.rend(), chars.begin(), chars.end());
	return found == str.rend() ? string::npos : pos - (found - start);
}
static int hexToInt(char hex)
{
	if (hex >= '0' && hex <= '9') return hex - '0';
	if (hex >= 'a' && hex <= 'f') return hex - 'a' + 10;
	if (hex >= 'A' && hex <= 'F') return hex - 'A' + 10;
	return 0;
}
static int hexPairToInt(const char *hex_pair)
{
	return hexToInt(hex_pair[0]) << 4 | hexToInt(hex_pair[1]);
}
bool ImportExport::importRGBTXT()
{
	ifstream f(m_filename.c_str(), ios::in);
	if (!f.is_open()){
		m_last_error = Error::could_not_open_file;
		return false;
	}
	string line;
	Color c;
	ColorObject* color_object;
	string strip_chars = " \t";
	for(;;){
		getline(f, line);
		if (!f.good()) break;
		stripLeadingTrailingChars(line, strip_chars);
		if (line.length() > 0 && line[0] == '#'){ // skip comment lines
			continue;
		}
		size_t hash_position = line.find('#');
		if (hash_position != string::npos){
			size_t last_non_space = rfind_first_of_not(line, hash_position, " \t");

			c.rgb.red = hexPairToInt(&line.at(hash_position + 1)) / 255.0;
			c.rgb.green = hexPairToInt(&line.at(hash_position + 3)) / 255.0;
			c.rgb.blue = hexPairToInt(&line.at(hash_position + 5)) / 255.0;

			color_object = color_list_new_color_object(m_color_list, &c);
			if (last_non_space != string::npos){
				color_object->setName(line.substr(0, last_non_space));
			}
			color_list_add_color_object(m_color_list, color_object, true);
			color_object->release();
		}
	}
	if (!f.eof()) {
		f.close();
		m_last_error = Error::file_read_error;
		return false;
	}
	f.close();
	return true;
}
static bool compareChunkType(const char *chunk_type, const char *data)
{
	int i;
	for (i = 0; i < 16; i++){
		if (chunk_type[i] != data[i]) return false;
		if (chunk_type[i] == 0) break;
	}
	for (; i < 16; i++){
		if (data[i] != 0) return false;
	}
	return true;
}
FileType ImportExport::getFileTypeByContent(const char *filename)
{
	ifstream f(filename, ios::in);
	if (!f.is_open())
		return FileType::unknown;
	char data[64];
	f.read(data, 64);
	size_t have = f.gcount();
	if (have >= 16){
		if (compareChunkType("GPA version", data))
			return FileType::gpa;
	}
	if (have >= 13){
		if (strncmp("GIMP Palette", data, 12) == 0 && (data[12] == '\r' || data[12] == '\n'))
			return FileType::gpl;
	}
	return FileType::unknown;
}
static struct{
	FileType type;
	const char *extension;
	bool full_name;
}extensions[] = {
	{FileType::gpa, ".gpa", false},
	{FileType::gpl, ".gpl", false},
	{FileType::ase, ".ase", false},
	{FileType::txt, ".txt", false},
	{FileType::mtl, ".mtl", false},
	{FileType::css, ".css", false},
	{FileType::html, ".html", false},
	{FileType::html, ".htm", false},
	{FileType::rgbtxt, "rgb.txt", true},
	{FileType::unknown, nullptr, false},
};
FileType ImportExport::getFileType(const char *filename)
{
	boost::filesystem::path path(filename);
	string name = path.filename().string();
	boost::algorithm::to_lower(name);
	for (size_t i = 0; extensions[i].type != FileType::unknown; ++i){
		if (extensions[i].full_name && name == extensions[i].extension){
			return extensions[i].type;
		}
	}
	string extension = path.extension().string();
	if (extension.length() == 0)
		return getFileTypeByContent(filename);
	boost::algorithm::to_lower(extension);
	for (size_t i = 0; extensions[i].type != FileType::unknown; ++i){
		if (!extensions[i].full_name && extension == extensions[i].extension){
			return extensions[i].type;
		}
	}
	return getFileTypeByContent(filename);
}
FileType ImportExport::getFileTypeByExtension(const char *extension)
{
	string extension_lowercase = extension;
	boost::algorithm::to_lower(extension_lowercase);
	for (size_t i = 0; extensions[i].type != FileType::unknown; ++i){
		if (!extensions[i].full_name && extension_lowercase == extensions[i].extension){
			return extensions[i].type;
		}
	}
	return FileType::unknown;
}
bool ImportExport::importType(FileType type)
{
	switch (type){
		case FileType::gpa:
			return importGPA();
		case FileType::gpl:
			return importGPL();
		case FileType::ase:
			return importASE();
		case FileType::txt:
			return importTXT();
		case FileType::rgbtxt:
			return importRGBTXT();
		case FileType::mtl:
		case FileType::css:
		case FileType::html:
		case FileType::unknown:
			return false;
	}
	return false;
}
ImportExport::Error ImportExport::getLastError() const
{
	return m_last_error;
}
struct ImportTextFile: public text_file_parser::TextFile
{
	ifstream m_file;
	list<Color> m_colors;
	bool m_failed;
	ImportTextFile(const string &filename)
	{
		m_failed = false;
		m_file.open(filename, ios::in);
	}
	bool isOpen()
	{
		return m_file.is_open();
	}
	virtual ~ImportTextFile()
	{
		m_file.close();
	}
	virtual void outOfMemory()
	{
		m_failed = true;
	}
	virtual void syntaxError(size_t start_line, size_t start_column, size_t end_line, size_t end_colunn)
	{
		m_failed = true;
	}
	virtual size_t read(char *buffer, size_t length)
	{
		m_file.read(buffer, length);
		size_t bytes = m_file.gcount();
		if (bytes > 0) return bytes;
		if (m_file.eof()) return 0;
		if (!m_file.good()){
			m_failed = true;
		}
		return 0;
	}
	virtual void addColor(const Color &color)
	{
		m_colors.push_back(color);
	}
};
bool ImportExport::importTextFile(const text_file_parser::Configuration &configuration)
{
	ImportTextFile import_text_file(m_filename);
	if (!import_text_file.isOpen()){
		m_last_error = Error::could_not_open_file;
		return false;
	}
	if (!import_text_file.parse(configuration)){
		m_last_error = Error::parsing_failed;
		return false;
	}
	if (import_text_file.m_failed){
		m_last_error = Error::parsing_failed;
		return false;
	}
	if (import_text_file.m_colors.size() == 0){
		m_last_error = Error::no_colors_imported;
		return false;
	}
	for (auto color: import_text_file.m_colors){
		auto color_object = new ColorObject("" ,color);
		color_list_add_color_object(m_color_list, color_object, true);
		color_object->release();
	}
	return true;
}
const std::string &ImportExport::getFilename() const
{
	return m_filename;
}

max_stars_repo_name: ryandesign/gpick

max_issues_repo_name: ryandesign/gpick

max_forks_repo_name: ryandesign/gpick


text:
//
// Copyright (c) 2009 Rutger ter Borg
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef BOOST_NUMERIC_BINDINGS_GLAS_DENSE_VECTOR_HPP
#define BOOST_NUMERIC_BINDINGS_GLAS_DENSE_VECTOR_HPP

#include <boost/numeric/bindings/detail/adaptor.hpp>
#include <glas/container/dense_vector.hpp>

namespace boost {
namespace numeric {
namespace bindings {
namespace detail {

template< typename T, typename Id, typename Enable >
struct adaptor< glas::dense_vector< T >, Id, Enable > {

    typedef typename copy_const< Id, T >::type value_type;
    typedef mpl::map<
        mpl::pair< tag::value_type, value_type >,
        mpl::pair< tag::entity, tag::vector >,
        mpl::pair< tag::size_type<1>, std::ptrdiff_t >,
        mpl::pair< tag::data_structure, tag::linear_array >,
        mpl::pair< tag::stride_type<1>, tag::contiguous >
    > property_map;

    static std::ptrdiff_t size1( const Id& id ) {
        return id.size();
    }

    static value_type* begin_value( Id& id ) {
        return id.storage_ptr();
    }

    static value_type* end_value( Id& id ) {
        return id.storage_ptr() + id.size();
    }

};

} // namespace detail
} // namespace bindings
} // namespace numeric
} // namespace boost

#endif

max_stars_repo_name: ljktest/siconos

max_issues_repo_name: ljktest/siconos

max_forks_repo_name: ljktest/siconos


text:
/*!
@file
Forward declares `boost::hana::Product`.

@copyright Louis Dionne 2014
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
 */

#ifndef BOOST_HANA_PRODUCT_PRODUCT_HPP
#define BOOST_HANA_PRODUCT_PRODUCT_HPP

#include <boost/hana/core/typeclass.hpp>
#include <boost/hana/detail/constexpr.hpp>

namespace boost { namespace hana {
    //! @ingroup group-typeclasses
    //! Represents types that are generic containers of two elements.
    //!
    //! Specifically, the `Product` type class represents types that are
    //! [category theoretical products][Wikipedia.Product].
    //!
    //! ### Laws
    //! For an instance `P` of `Product`, the following laws must be satisfied,
    //! which is equivalent to satisfying the universal property exposed in
    //! the article linked above. For every data types `X`, `P1`, `P2` and
    //! functions `f : X -> P1`, `g : X -> P2`, there exists a unique function
    //! `make : X -> P` such that for all object `x` of data type `X`,
    //! @code
    //!     f(x) == first(make(x))
    //!     g(x) == second(make(x))
    //! @endcode
    //!
    //! This is basically saying that a `Product` must be the most general
    //! object able to contain a pair of objects `(P1, P2)`, but nothing
    //! more. Since the categorical product is defined by a universal
    //! property, all instances are unique up to isomorphism.
    //!
    //!
    //! [Wikipedia.Product]: http://en.wikipedia.org/wiki/Product_(category_theory)
    struct Product {
        BOOST_HANA_TYPECLASS(Product);
        struct mcd;
    };

    //! Creates a `Product` of the two given elements.
    //! @relates Product
    //!
    //!
    //! @tparam P
    //! The data type (an instance of `Product`) of the product to create.
    //!
    //! @param fst
    //! The first element of the resulting product.
    //!
    //! @param snd
    //! The second element of the resulting product.
    //!
    //!
    //! ### Example
    //! @snippet example/product/make_product.cpp main
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    template <typename P>
    constexpr auto make_product = [](auto fst, auto snd) {
        return Product::instance<
            datatype_t

        >::make_product_impl(fst, snd);
    };
#else
    namespace product_detail {
        template <typename P>
        struct make_product {
            template <typename Fst, typename Snd>
            constexpr auto operator()(Fst fst, Snd snd) const {
                return Product::instance<
                    datatype_t

                >::make_product_impl(fst, snd);
            }
        };
    }

    template <typename P>
    constexpr product_detail::make_product
 make_product{};
#endif

    //! Return the first element of a product.
    //! @relates Product
    //!
    //! ### Example
    //! @snippet example/product/first.cpp main
    BOOST_HANA_CONSTEXPR_LAMBDA auto first = [](auto product) {
        return Product::instance<
            datatype_t<decltype(product)>
        >::first_impl(product);
    };

    //! Return the second element of a product.
    //! @relates Product
    //!
    //! ### Example
    //! @snippet example/product/second.cpp main
    BOOST_HANA_CONSTEXPR_LAMBDA auto second = [](auto product) {
        return Product::instance<
            datatype_t<decltype(product)>
        >::second_impl(product);
    };
}} // end namespace boost::hana

#endif // !BOOST_HANA_PRODUCT_PRODUCT_HPP

max_stars_repo_name: rbock/hana

max_issues_repo_name: rbock/hana

max_forks_repo_name: rbock/hana


text: #include <boost/log/keywords/filter.hpp>