text:
#include <iostream>
#include <boost/cstdint.hpp>

inline const boost::uint_least32_t UnSynch(const boost::uint_least32_t & uValue)
{
    return (uValue & 0x7Fu) | ((uValue & (0x7Fu<<8u))>>1) | ((uValue & (0x7Fu<<16u))>>2) | ((uValue & (0x7Fu<<24u))>>3);
}
inline const boost::uint_least32_t Synch(const boost::uint_least32_t & uValue)
{
    return (uValue & 0x7Fu) | ((uValue & (0x7Fu<<7u))<<1) | ((uValue & (0x7Fu<<14u))<<2) | ((uValue & (0x7Fu<<21u))<<3);
}
inline const bool ValidSynch(const boost::uint_least32_t & uValue)
{
    return !(uValue & 0x80808080u);
}
int main()
{
    boost::uint_least32_t uValue = 0x0FFFFFFFu;
    std::cout << "Value: " << uValue << std::endl;
    uValue = Synch(uValue);
    std::cout << "Value: " << uValue << std::endl;
    uValue = UnSynch(uValue);
    std::cout << "Value: " << uValue << std::endl;
    return 0;
}

max_stars_repo_name: nacitar/old-projects

max_issues_repo_name: nacitar/old-projects

max_forks_repo_name: nacitar/old-projects


text:
#include <boost/thread/thread.hpp>

int main() {
  boost::thread t;
  t.join();  // do nothing
  return 0;
}

ext: cpp

max_stars_repo_name: melonedo/cmake-lecture

max_issues_repo_name: melonedo/cmake-lecture

max_forks_repo_name: melonedo/cmake-lecture


text: #include <boost/spirit/include/classic_common_fwd.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
/*
 * The Shadow Simulator
 *
 * Copyright (c) 2010-2012 Rob Jansen <jansen@cs.umn.edu>
 *
 * This file is part of Shadow.
 *
 * Shadow is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Shadow 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Shadow.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "shd-html.hpp"
#include <assert.h>
#include <map>
#include <boost/algorithm/string.hpp>

using std::vector;
using std::map;
using std::string;

static string html_parse_img(const map<string, string>& attrs) {
    return attrs.at("src");
}

static string html_parse_link(const map<string, string>& attrs) {
    const string& rel = attrs.at("rel");
    const string& source = attrs.at("href");

    if (rel == "stylesheet") {
        return source;
    }

    if (rel == "shortcut icon") {
        return source;
    }

    return "";
}

static map<string, string>* html_get_attributes(TidyNode node) {
    TidyAttr curr_attr = tidyAttrFirst(node);
    map<string, string>* attrs = new map<string, string>();

    while(curr_attr) {
        gchar* canonical_name = g_utf8_strdown(tidyAttrName(curr_attr), -1);
        const ctmbstr value = tidyAttrValue(curr_attr);
        (*attrs)[string(canonical_name)] = string(value ? value : "");
        g_free(canonical_name);
        curr_attr = tidyAttrNext(curr_attr);
    }

    return attrs;
}

static void html_find_objects(TidyDoc tdoc, TidyNode node,
                              vector<string>& images,
                              vector<ScriptResource>* scripts)
{
    TidyNode child;

    for (child = tidyGetChild(node); child; child = tidyGetNext(child)) {
        map<string, string>* attrs = html_get_attributes(child);

        const gchar* name = NULL;
        if ((name = tidyNodeGetName(child))) {
            string url;
            if (g_ascii_strncasecmp(name, "img", 3) == 0) {
                images.push_back(html_parse_img(*attrs));
            } else if (scripts
                       && g_ascii_strncasecmp(name, "script", 6) == 0)
            {
                TidyBuffer buf = {0};
                tidyNodeGetText(tdoc, child, &buf);
                //printf("[%s]___\n", buf.bp);
                string s((const char*)buf.bp, buf.size);
                tidyBufFree(&buf);

                scripts->resize(scripts->size() + 1);
                ScriptResource& sr = scripts->back();
                if (attrs->find("src") != attrs->end()) {
                    sr.src = attrs->at("src");
                }

                boost::trim(s);
                boost::split(sr.lines, s, boost::is_any_of("\n"));
                // remove the first & last lines
                sr.lines.erase(sr.lines.end()); // the "</script>" line
                sr.lines.erase(sr.lines.begin()); // the "<script type= ...>" line
            } else if (g_ascii_strncasecmp(name, "link", 4) == 0) {
                url = html_parse_link(*attrs);
            }
        }
        delete attrs;

        html_find_objects(tdoc, child, images, scripts);
    }
}

void html_parse(const gchar* html, vector<string>& images,
                vector<ScriptResource>* scripts)
{
    TidyDoc tdoc = tidyCreate();
    TidyBuffer tidy_errbuf = {0};
    int err = 0;

    tidyOptSetBool(tdoc, TidyForceOutput, yes); /* try harder */
    tidyOptSetInt(tdoc, TidyWrapLen, 4096);
    tidySetErrorBuffer( tdoc, &tidy_errbuf );

    err = tidyParseString(tdoc, html); /* parse the input */

    if ( err >= 0 ) {
        err = tidyCleanAndRepair(tdoc); /* fix any problems */

        if ( err >= 0 ) {
            err = tidyRunDiagnostics(tdoc); /* load tidy error buffer */

            if ( err >= 0 ) {
                html_find_objects(tdoc, tidyGetHtml(tdoc),
                                  images, scripts); /* walk the tree */
            }
        }
    }
    tidyBufFree(&tidy_errbuf);
    tidyRelease(tdoc);
}

ext: cc

max_stars_repo_name: akshayeshenoi/shadow-plugin-extras

max_issues_repo_name: akshayeshenoi/shadow-plugin-extras

max_forks_repo_name: akshayeshenoi/shadow-plugin-extras


text:
// Copyright David Abrahams 2001.
// 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 <boost/python/type_id.hpp>
#include <boost/python/detail/decorated_type_id.hpp>
#include <utility>
#include <vector>
#include <algorithm>
#include <memory>
#include <cstdlib>
#include <cstring>

#if defined(__QNXNTO__)
# include <ostream>
#else                       /*  defined(__QNXNTO__) */

#if !defined(__GNUC__) || __GNUC__ >= 3 || __SGI_STL_PORT || __EDG_VERSION__
# include <ostream>
#else
# include <ostream.h>
#endif

#  ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
#   if defined(__GNUC__) &&  __GNUC__ >= 3

// http://lists.debian.org/debian-gcc/2003/09/msg00055.html notes
// that, in cxxabi.h of gcc-3.x for x < 4, this type is used before it
// is declared.
#    if __GNUC__ == 3 && __GNUC_MINOR__ < 4
class __class_type_info;
#    endif

#    include <cxxabi.h>
#   endif
#  endif
#endif                      /*  defined(__QNXNTO__) */

namespace boost { namespace python {

#  ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE

#   if defined(__QNXNTO__)
namespace cxxabi {
extern "C" char* __cxa_demangle(char const*, char*, std::size_t*, int*);
}
#   else                    /*  defined(__QNXNTO__) */

#    ifdef __GNUC__
#     if __GNUC__ < 3

namespace cxxabi = :: ;
extern "C" char* __cxa_demangle(char const*, char*, std::size_t*, int*);
#     else

namespace cxxabi = ::abi;       // GCC 3.1 and later

#      if __GNUC__ == 3 && __GNUC_MINOR__ == 0
namespace abi
{
  extern "C" char* __cxa_demangle(char const*, char*, std::size_t*, int*);
}
#      endif            /*  __GNUC__ == 3 && __GNUC_MINOR__ == 0    */
#     endif             /*  __GNUC__ < 3                            */
#    endif              /*  __GNUC__                                */
#   endif               /*  defined(__QNXNTO__)                     */

namespace
{
  struct compare_first_cstring
  {
      template <class T>
      bool operator()(T const& x, T const& y)
      {
          return std::strcmp(x.first,y.first) < 0;
      }
  };

  struct free_mem
  {
      free_mem(char*p)
          : p(p) {}

      ~free_mem()
      {
          std::free(p);
      }
      char* p;
  };
}

bool cxxabi_cxa_demangle_is_broken()
{
    static bool was_tested = false;
    static bool is_broken = false;
    if (!was_tested) {
        int status;
        free_mem keeper(cxxabi::__cxa_demangle("b", 0, 0, &status));
        was_tested = true;
        if (status == -2 || strcmp(keeper.p, "bool") != 0) {
          is_broken = true;
        }
    }
    return is_broken;
}

namespace detail
{
  BOOST_PYTHON_DECL char const* gcc_demangle(char const* mangled)
  {
      typedef std::vector<
          std::pair<char const*, char const*>
      > mangling_map;

      static mangling_map demangler;
      mangling_map::iterator p
          = std::lower_bound(
              demangler.begin(), demangler.end()
            , std::make_pair(mangled, (char const*)0)
            , compare_first_cstring());

      if (p == demangler.end() || strcmp(p->first, mangled))
      {
          int status;
          free_mem keeper(
              cxxabi::__cxa_demangle(mangled, 0, 0, &status)
              );

          assert(status != -3); // invalid argument error

          if (status == -1)
          {
              throw std::bad_alloc();
          }
          else
          {
              char const* demangled
                = status == -2
                  // Invalid mangled name.  Best we can do is to
                  // return it intact.
                  ? mangled
                  : keeper.p;

              // Ult Mundane, 2005 Aug 17
              // Contributed 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)
              // The __cxa_demangle function is supposed to translate
              // builtin types from their one-character mangled names,
              // but it doesn't in gcc 3.3.5 and gcc 3.4.x.
              if (cxxabi_cxa_demangle_is_broken()
                  && status == -2 && strlen(mangled) == 1)
              {
                  // list from
                  // http://www.codesourcery.com/cxx-abi/abi.html
                  switch (mangled[0])
                  {
                      case 'v': demangled = "void"; break;
                      case 'w': demangled = "wchar_t"; break;
                      case 'b': demangled = "bool"; break;
                      case 'c': demangled = "char"; break;
                      case 'a': demangled = "signed char"; break;
                      case 'h': demangled = "unsigned char"; break;
                      case 's': demangled = "short"; break;
                      case 't': demangled = "unsigned short"; break;
                      case 'i': demangled = "int"; break;
                      case 'j': demangled = "unsigned int"; break;
                      case 'l': demangled = "long"; break;
                      case 'm': demangled = "unsigned long"; break;
                      case 'x': demangled = "long long"; break;
                      case 'y': demangled = "unsigned long long"; break;
                      case 'n': demangled = "__int128"; break;
                      case 'o': demangled = "unsigned __int128"; break;
                      case 'f': demangled = "float"; break;
                      case 'd': demangled = "double"; break;
                      case 'e': demangled = "long double"; break;
                      case 'g': demangled = "__float128"; break;
                      case 'z': demangled = "..."; break;
                  }
              }

              p = demangler.insert(p, std::make_pair(mangled, demangled));
              keeper.p = 0;
          }
      }

      return p->second;
  }
}
#  endif

BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, type_info const& x)
{
    return os << x.name();
}

namespace detail
{
  BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, detail::decorated_type_info const& x)
  {
      os << x.m_base_type;
      if (x.m_decoration & decorated_type_info::const_)
          os << " const";
      if (x.m_decoration & decorated_type_info::volatile_)
          os << " volatile";
      if (x.m_decoration & decorated_type_info::reference)
          os << "&";
      return os;
  }
}
}} // namespace boost::python::converter

max_stars_repo_name: Faham/bric-n-brac

max_issues_repo_name: Faham/bric-n-brac

max_forks_repo_name: Faham/bric-n-brac


text:
struct spinlock_t {
    bool try_lock() {
        static int i = 0;
        return i++ >= 100;
    }
};

struct port_t {
    bool block_ready() {
        static int i = 0;
        return i++ >= 10;
    }
};

#include <boost/version.hpp>

// Coroutines changed interface in Boost 1.56
#if BOOST_VERSION < 105600

#include <boost/coroutine/coroutine.hpp>

typedef boost::coroutines::coroutine<
    std::string&(std::size_t max_characters_to_process)
> corout_t;

void coroutine_task(corout_t::caller_type& caller) {
    std::string result;
    // Returning back to main programm
    caller(result);

    while (1) {
        std::size_t max_characters_to_process = caller.get();

        // Do process some characters
        // ...
        result.resize(result.size() + max_characters_to_process);

        // Returning result, switching back
        // to main program
        caller(result);
    } /*while*/
}

void coroutine_task(corout_t::caller_type& caller);

int main() {
    corout_t coroutine(coroutine_task);

    // Doing some work
    // ...
    spinlock_t spinlock;
    port_t port;

    while (!spinlock.try_lock()) {
        // We may do some usefull work, before
        // attempting to lock a spinlock once more
        coroutine(10); // Small delays
    }
    // Spinlock is locked
    // ...
    assert(coroutine.get().size() == 10 * 100);
    coroutine.get().clear();

    while (!port.block_ready()) {
        // We may do some usefull work, before
        // attempting to get block of data once more
        coroutine(300);  // Bigger delays
        std::string& s = coroutine.get();
        // ...
        (void)s;
    }

    assert(coroutine.get().size() == 10 * 300);
}

#else

#include <boost/coroutine/coroutine.hpp>

typedef boost::coroutines::asymmetric_coroutine<std::size_t> corout_t;

struct coroutine_task {
    std::string& result;

    explicit coroutine_task(std::string& result_in)
        : result(result_in)
    {}

    void operator()(corout_t::pull_type& yield) {
        while (1) {
            std::size_t max_characters_to_process = yield.get();

            // Do process some characters
            // ...
            result.resize(result.size() + max_characters_to_process);

            // Returning result, switching back
            // to main program
            yield();
        } /*while*/
    }
};

int main() {
    std::string result;
    coroutine_task task(result);
    corout_t::push_type coroutine(task);

    // Doing some work
    // ...
    spinlock_t spinlock;
    port_t port;

    while (!spinlock.try_lock()) {
        // We may do some usefull work, before
        // attempting to lock a spinlock once more
        coroutine(10); // Small delays
    }
    // Spinlock is locked
    // ...
    assert(result.size() == 10 * 100);
    result.clear();

    while (!port.block_ready()) {
        // We may do some usefull work, before
        // attempting to get block of data once more
        coroutine(300);  // Bigger delays
        // Do something with `result` variable
    }

    assert(result.size() == 10 * 300);
}

#endif // BOOST_VERSION < 105600


text:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <utility>
#include <cassert>
#include <set>
#include <leveldb/db.h>
// #include "boost_logger.hpp"
#include "utf8.h"
#include "logger.hpp"
#include <boost/filesystem.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include "boost/format.hpp"

#include <boost/serialization/utility.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/map.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>

#include <ctime>

namespace fs = boost::filesystem;
using namespace std;

// Global variable
leveldb::DB *g_db;
bool g_rebuild = true;
long DATA_MAX_SIZE = (1024 * 1);
long SLICE_WRITE_SIZE = (1024 * 1024 * 10);
string g_data_path;
string g_index_path;
string g_db_path;
auto g_ch_size = sizeof (unsigned short);
auto g_offset = g_ch_size * 4;
vector<string> g_docs;
map<int, string> g_id2file_map;
map<string, int> g_file2id_map;
map<string, pair<int,long> > g_file2dataid_pos_map;
map<int, pair<int, long > > g_doc2startpos_map;
map<string, int> g_char2slice_map;

void u16_2_u8(const vector<unsigned short> & utf16line, string & line_out);
string ch_2_u8(unsigned short ch);
void clean_line(string & line);
template<class type> void compose_data_name(const type & outfile_index, string & outFileName);

void clean_line(string & line) {
    if (!line.empty() && line[line.size() - 1] == '\r') {
        line.erase(line.size() - 1);
    }
}

bool create_dir(const char * index_path) {
    if (g_rebuild) {
        fs::remove_all(index_path);
    }
    if (!fs::exists(index_path)) {
        fs::create_directory(index_path);
        LogInfo("Creating: %s dir", index_path);
    } else {
        LogInfo("Use %s dir" , index_path);
    }
    return true;
}

template<class type> void compose_data_name(const type & outfile_index, string & outFileName) {
    fs::path dir(g_index_path);
    outFileName = str( boost::format("DATA_%#05x") % outfile_index );
    outFileName = (dir / fs::path(outFileName)).string();
}

template<class type1, class type2> void compose_two_key(const type1 & key1, const type2 & key2, string & keyName) {
    keyName = str( boost::format("%d_%#05x_%#05x") % key1 % key1 % key2); // From 0 to N
}
template<class type1, class type2> void compose_slice_key(const type1 & key1, const type2 & key2, string & keyName) {
    keyName = str( boost::format("%s_%#05x") % key1 % key2); // From 0 to N
}
void find_section(vector < pair < int, long > > & A,
        vector < pair < int, long > > & B,
        vector < pair < int, long > > & C,
        int pos=1) {
    auto i = 0l;
    auto j = 0l;
    C.clear();
    for ( ; i < A.size(); i++) {
        pair<int, long> a_pos = A[i];
        for ( ; j < B.size(); j++) {
            pair<int, long> b_pos = B[j];
            if (a_pos.first < b_pos.first) {
                break;  // Wait for i
            } else if (a_pos.first == b_pos.first) {
                if ( ( b_pos.second - a_pos.second ) <= pos && ( b_pos.second > a_pos.second ) ) {
                    C.push_back(make_pair(b_pos.first, b_pos.second));  // Add the pos
                }
                if (b_pos.second > a_pos.second) {
                    break;
                } else {
                    continue;
                }
            } else {
                continue;  // Wait for j
            }
        }
        if ( j == B.size() ) {
            return ;
        }
    }
}

struct recursive_directory_range {
    typedef fs::recursive_directory_iterator iterator;
    recursive_directory_range(fs::path p) : p_(p) {}

    iterator begin() {
        return fs::recursive_directory_iterator(p_);
    }
    iterator end() {
        return fs::recursive_directory_iterator();
    }

    fs::path p_;
};

bool init_db(const string & dbpath, leveldb::DB ** db) {
    if (g_rebuild) {
        create_dir(dbpath.c_str());
    }
    leveldb::Options options;
    options.create_if_missing = true;
    leveldb::Status status = leveldb::DB::Open( options, dbpath, db );
    assert ( status.ok() );
    return true;
}

bool save_db(const string & key, const string & value) {
    // clock_t tStart = clock();
    leveldb::Status sta;
    sta = g_db->Put( leveldb::WriteOptions(), key, value);
    // printf("Time taken: %.9fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
    if ( sta.ok() ) {
        return true;
    }
    return false;
}

bool get_db(const string & key, string & value) {

    //clock_t tStart = clock();
    leveldb::Status sta;
    sta = g_db->Get( leveldb::ReadOptions(), key, &value );
    //printf("Time taken: %.9fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
    if ( sta.ok() ) {
        return true;
    }
    return false;
}

bool get_all_file(const char * path, vector<string> & vs) {
    try {
        for (auto it : recursive_directory_range(path)) {
            vs.push_back(it.path().string());
        }
        return true;
    } catch (exception& e) {
        LogFatal(e.what());
        return false;
    }
}

void write_string_record(ofstream & of, const string & filename) {
    long c = filename.size();
    of.write(reinterpret_cast<char *>(&c),  sizeof(c));
    of.write(reinterpret_cast<const char *>(filename.c_str()), c);
}

void read_string_record(ifstream & ifs, stringstream & istr) {
    long count = 0;
    ifs.read(reinterpret_cast<char *>(&count), sizeof(count));
    unique_ptr<char []> tmp(new char[count]);
    ifs.read(reinterpret_cast<char *>(tmp.get()), count);
    istr.write(tmp.get(), count);
}

template <class type1 > void str_2_obj(stringstream & in, type1 & out) {
    boost::archive::binary_iarchive ia(in);
    ia >> out;
}

template <class type1, class type2> void set_or_plus(type1 & m, const type2 & k) {
    if (m.find(k) != m.end()) {
        m[k] = m[k] + 1;
    } else {
        m[k] = 0;
    }
}

template <class type1, class type2, class type3> void set_or_pushback(type1 & m,
        const type2 & k,
        const type3 & v) {
    if (m.find(k) != m.end()) {
        m[k].push_back(v);
    } else {
        vector< pair<int, long> > vc;
        m[k] = vc;
        m[k].push_back(v);
    }
}

template <class type1> void obj_2_str(const type1 & in, string & out) {
    stringstream ostr;
    boost::archive::binary_oarchive oa(ostr);
    oa << in;
    out = ostr.str();
}

template <class type1, class type2, class type3, class type4> void write_slice_record(type1 & char2count_map,
        type2 & char2slice_map,
        type3 & char2pos_map,
        type4 & key) {
    try {
        char2count_map[key] = 0;
        vector < pair<int, long> > & ref = char2pos_map[key];
        string out;
        obj_2_str<vector <pair <int, long > > > (ref, out);
        set_or_plus(char2slice_map, key);
        string keyName;  // From 0 to N
        compose_slice_key(key, char2slice_map[key], keyName);
        save_db(keyName, out);  // Save the vector to db
        ref.clear();
    } catch (exception& e) {
        LogFatal(e.what());
    }
}

string ch_2_u8(unsigned short ch) {
    vector<unsigned short> vs;
    vs.push_back(ch);
    string s;
    u16_2_u8(vs, s);
    return s;
}

template <class type1, class type2> void clear_write(type1 & char2pos_map,
        type2 & char2count_map,
        type2 & char2slice_map
        ) {
    for (auto it: char2pos_map) {
        write_slice_record(char2count_map, char2slice_map, char2pos_map, it.first);
    }
}

void u8_2_u16(string & line, vector<unsigned short> & utf16line) {
    string::iterator end_it = utf8::find_invalid(line.begin(), line.end());
    utf8::utf8to16(line.begin(), end_it, back_inserter(utf16line));
}

void u16_2_u8(const vector<unsigned short> & utf16line, string & line_out) {
    utf8::utf16to8(utf16line.begin(), utf16line.end(), back_inserter(line_out));
}

bool build_index(const char * index_path) {
    try {

        vector<string> vs;
        get_all_file(g_data_path.c_str(), vs);

        create_dir(index_path);
        fs::path dir(index_path);
        fs::path file("_index");
        fs::path full_path = dir / file;
        ofstream fidx(full_path.string(), ios::binary);
        if (!fidx) {
            LogFatal("Can not open %s", full_path.string().c_str());
        }
        map<int, string> id2file_map;
        map<string, int> file2id_map;
        map<string, pair<int,long> > file2dataid_pos_map;
        map<int, pair<int, long > > doc2startpos_map;  // The pos which doc data store in data file  <data_file_id, pos>

        map<string, vector< pair<int, long> > > char2pos_map; // char_char to <doc_id, doc_offset>
        map<string, int> char2count_map;  // Current char_char times count, use for write db count
        map<string, int> char2slice_map;  // Slice count from like A_A_0 A_A_1 A_B_0

        int count = 0;
        for (auto it: vs) {
            file2id_map[it] = count;
            id2file_map[count] = it;
            count++;
        }

        long outfile_index = 0;
        long outfile_count = DATA_MAX_SIZE + 10000;  // record current fileCount
        long writer_pos = 0;

        ofstream outfile;

        string out;
        obj_2_str<vector<string> > (vs, out);
        write_string_record(fidx, out);

        for (auto filename: vs) {
            LogInfo("Indexing : %s" , filename.c_str());

            if (outfile_index == 0) {
                doc2startpos_map[file2id_map[filename]] = make_pair(outfile_index, writer_pos);
            } else {
                doc2startpos_map[file2id_map[filename]] = make_pair(outfile_index - 1, writer_pos);
            }

            ifstream infile(filename);
            long char_offset = 0;

            string line;
            auto linecount = 0;
            while (std::getline(infile, line)) {
                clean_line(line);
                if (++linecount % 10000 == 0) {
                    LogInfo("Line: %d" , linecount);
                }

                vector<unsigned short> utf16line;
                u8_2_u16(line, utf16line);
                unsigned short pre_ch = 0xFF;

                for (auto u16char: utf16line) {
                    string new_key;

                    compose_two_key(pre_ch, u16char, new_key);
                    {
                        set_or_plus(char2count_map, new_key);
                        set_or_pushback(char2pos_map, new_key, make_pair(file2id_map[filename], char_offset) );
                        if (char2count_map[new_key] >= SLICE_WRITE_SIZE ) {
                            write_slice_record(char2count_map, char2slice_map, char2pos_map, new_key);
                        }
                    }
                    if (pre_ch != 0xFF)
                    {
                        compose_two_key(0xFF, u16char, new_key);
                        set_or_plus(char2count_map, new_key);
                        set_or_pushback(char2pos_map, new_key, make_pair(file2id_map[filename], char_offset) );
                        if (char2count_map[new_key] >= SLICE_WRITE_SIZE ) {
                            write_slice_record(char2count_map, char2slice_map, char2pos_map, new_key);
                        }
                    }
                    if (outfile_count >= DATA_MAX_SIZE) {
                        // Create new file
                        outfile_count = 0;
                        writer_pos = 0;
                        string outFileName;
                        compose_data_name<int>(outfile_index, outFileName);
                        outfile.close();
                        outfile.open(outFileName);
                        outfile_index++;
                    }

                    outfile.write(reinterpret_cast<char *>(&u16char),  g_ch_size);  // write char to file
                    outfile_count += g_ch_size;
                    writer_pos += g_ch_size;
                    char_offset++;
                    pre_ch = u16char;
                }
            }
        }

        // write_info2indexfile

        obj_2_str< map<int, string> > (id2file_map, out);
        write_string_record(fidx, out);
        obj_2_str< map<string, int> > (file2id_map, out);
        write_string_record(fidx, out);
        obj_2_str< map<string, pair<int,long> > > (file2dataid_pos_map, out);
        write_string_record(fidx, out);
        obj_2_str< map<int, pair<int, long > >  > (doc2startpos_map, out);
        write_string_record(fidx, out);

        clear_write(char2pos_map, char2count_map, char2slice_map);  // Write the last bucket to the db

        obj_2_str< map<string, int>  > (char2slice_map, out);
        write_string_record(fidx, out);

        return true;
    } catch (exception& e) {
        LogFatal(e.what());
        return false;
    }
}

template <class type1> void read_obj(ifstream & fin, type1 & obj) {
    stringstream sbuf;
    read_string_record(fin, sbuf);
    str_2_obj(sbuf, obj);
}

bool read_index(const char * index_path) {
    try {
        fs::path dir(index_path);
        fs::path file("_index");
        fs::path full_path = dir / file;
        ifstream fidx(full_path.string(), ios::binary);
        if (!fidx) {
            LogFatal("Can not open %s" , full_path.string().c_str());
        }
        LogInfo("Reading index %s ", full_path.string().c_str());
        read_obj(fidx, g_docs);
        read_obj(fidx, g_id2file_map);
        read_obj(fidx, g_file2id_map);
        read_obj(fidx, g_file2dataid_pos_map);
        read_obj(fidx, g_doc2startpos_map);
        read_obj(fidx, g_char2slice_map);
        return true;
    } catch (exception& e) {
        LogFatal(e.what());
        return false;
    }
}

void load_config(const char * path) {
    boost::property_tree::ptree pt;
    boost::property_tree::ini_parser::read_ini(path, pt);
    g_data_path = pt.get<string>("all.data_path");
    g_index_path = pt.get<string>("all.index_path");
    g_db_path = pt.get<string>("all.db_path");
    g_rebuild = pt.get<bool>("all.rebuild");
    DATA_MAX_SIZE = pt.get<int>("all.data_max_size") * g_ch_size;
    SLICE_WRITE_SIZE = pt.get<int>("all.slice_write_size");
    g_offset = pt.get<int>("all.return_windows") * g_ch_size;
}

void get_slice_vec(const string & ch, vector< pair < int, long > > & vc) {
    vc.clear();
    if (g_char2slice_map.find(ch) == g_char2slice_map.end()) {
        return ;  // Not in
    }
    for(int i = 0; i <= g_char2slice_map[ch]; i++) {
        string keyName;
        compose_slice_key(ch, i, keyName);
        string value;
        if(get_db(keyName, value)) {
            vector<pair<int, long>> tv;
            stringstream ss(value);
            str_2_obj(ss, tv);
            vc.reserve( vc.size() + tv.size() );                // preallocate memory without erase original data
            vc.insert( vc.end(), tv.begin(), tv.end() );
        } else {
            LogFatal("No in db");
        }
    }
}

template <class type> void _compute_true_doc_pos(pair<int, long> & dat_pos, const type & pos) {
    auto true_pos = (dat_pos.second + pos * g_ch_size);
    auto doc_offset = true_pos / DATA_MAX_SIZE;
    dat_pos.second = true_pos % DATA_MAX_SIZE;
    dat_pos.first += doc_offset;
}

void _get_doc(pair<int, long> doc_pos, string & st, const int & len) {
    pair<int, long> dat_pos = g_doc2startpos_map[doc_pos.first];
    _compute_true_doc_pos(dat_pos, doc_pos.second);
    string filename;
    compose_data_name<int> (dat_pos.first, filename);
    long start_pos = dat_pos.second - (len - 1) * g_ch_size - g_offset;
    if (start_pos < 0) {
        start_pos = 0;
    }
    long end_pos = dat_pos.second + g_ch_size + g_offset;
    if (end_pos > DATA_MAX_SIZE) {
        end_pos = DATA_MAX_SIZE;
    }
    vector<unsigned short> vc;
    ifstream fin(filename);
    if (!fin) {
        LogFatal("Not open %s" , filename.c_str());
    }
    fin.seekg(start_pos);
    unsigned short ch;
    auto i = 0;
    while(fin.read(reinterpret_cast<char *>(& ch), g_ch_size)) {
        i += g_ch_size;
        if (i > end_pos - start_pos) {
            break;
        }
        vc.push_back(ch);
    }
    // cout << "Str len " << vc.size() <<" " <<start_pos  <<" : " <<end_pos <<endl;
    u16_2_u8(vc, st);
}

void _get_string_from_doc_pos(vector<pair<int, long> > doc_pos, vector<string> & sout, const int & len) {
    for (auto pos: doc_pos) {
        string st;
        _get_doc(pos, st, len);
        sout.push_back(st);
        // cout <<"Find " <<count <<" " << st <<endl;
    }
}

void _search(const vector<unsigned short> & utf16line, vector<string> & sout) {
    vector<pair<int, long>> A, B, C;
    bool first = true;
    unsigned short pre_ch = 0xFF;

    for (auto ch: utf16line) {
        string new_key;
        compose_two_key(pre_ch, ch, new_key);
        pre_ch = ch;
        if (first) {
            first = false;
            get_slice_vec(new_key, A);  // The first run
            continue;
        }
        if (A.size() == 0) {
            break; // Not found
        }
        get_slice_vec(new_key, B);
        find_section(A, B, C);
        A = C;
    }
    _get_string_from_doc_pos(A, sout, utf16line.size());
}

void search(string & line) {
    vector<unsigned short > utf16line;
    u8_2_u16(line, utf16line);
    vector<string> sout;
    _search(utf16line, sout);
    auto lineNum = 0;
    for ( auto i: sout) {
        lineNum++;
        cout <<"Line " <<lineNum <<": " << i <<endl;
    }
}
void search_loop() {
    while(true) {
        string sin;
        cout <<"Pls input word to search" <<endl;
        cin >> sin;
        search(sin);
    }
}

int main(int argc, char ** argv) {
    try {
        load_config(argv[1]);

        // g_InitLog();
        init_db(g_db_path, &g_db);

        if (g_rebuild) {
            build_index(g_index_path.c_str());
        }

        read_index(g_index_path.c_str());

        search_loop();

    } catch (exception& e) {
        LogFatal(e.what());
    }
}


text:
/*
 Copyright (c) 2015 Siyu Lei, Silviu Maniu, Luyi Mo (University of Hong Kong)

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */

#ifndef __oim__DiscountDegreeEvaluator__
#define __oim__DiscountDegreeEvaluator__

#include "common.hpp"
#include "Evaluator.hpp"

#include <boost/heap/fibonacci_heap.hpp>

class DiscountDegreeEvaluator : public Evaluator {
 public:
  std::unordered_set<unode_int> select(
        const Graph& graph, Sampler& sampler,
        const std::unordered_set<unode_int>& activated, unsigned int k) {
    std::unordered_set<unode_int> set;
    unsigned int type = sampler.get_type();
    boost::heap::fibonacci_heap<NodeType> queue;
    std::unordered_map<unode_int,
        boost::heap::fibonacci_heap<NodeType>::handle_type> queue_nodes;
    for (unode_int node : graph.get_nodes()) {
      NodeType nstruct;
        nstruct.id = node;
        nstruct.deg = activated.find(node) == activated.end() ? 1.0f : 0.0f;
        if (graph.has_neighbours(node)) {
          for (auto edge : graph.get_neighbours(node)) {
            if(activated.find(edge.target) == activated.end()) {
              nstruct.deg += edge.dist->sample(type);
            }
          }
        }
        queue_nodes[node] = queue.push(nstruct);
    }
    while (set.size() < k && (!queue.empty())) {
      NodeType nstruct = queue.top();
      set.insert(nstruct.id);
      for (auto edge : graph.get_neighbours(nstruct.id)) {
        if (activated.find(edge.target) == activated.end() &&
            set.find(edge.target) == set.end()) {
          NodeType newnstruct = *queue_nodes[edge.target];
          newnstruct.id = edge.target;
          newnstruct.deg = newnstruct.deg*(1.0f - edge.dist->sample(type));
          queue.update(queue_nodes[edge.target], newnstruct);
        }
      }
      queue.pop();
    }
    queue_nodes.clear();
    return set;
  }
};

#endif /* defined(__oim__DiscountDegreeEvaluator__) */

max_stars_repo_name: smaniu/oim

max_issues_repo_name: smaniu/oim

max_forks_repo_name: smaniu/oim


text:
//------------------------------------------------------------------------------
/// \file CreateOrOpen_tests.cpp
/// \author Ernest Yeung
/// \email  ernestyalumni@gmail.com
//------------------------------------------------------------------------------
#include "IPC/MessageQueue/CreateOrOpen.h"

#include "Cpp/Utilities/TypeSupport/UnderlyingTypes.h"
#include "IPC/MessageQueue/FlagsModesAttributes.h"
#include "IPC/MessageQueue/MessageQueueDescription.h"
#include "Tools/TemporaryDirectory.h"

#include <boost/test/unit_test.hpp>
#include <iostream>
#include <string>

using Cpp::Utilities::TypeSupport::get_underlying_value;
using IPC::MessageQueue::AdditionalOperationFlags;
using IPC::MessageQueue::Close;
//using IPC::MessageQueue::CreateOrOpen;
using IPC::MessageQueue::ModePermissions;
using IPC::MessageQueue::NoAttributesOpen;
using IPC::MessageQueue::OpenConfiguration;
using IPC::MessageQueue::OperationFlags;
using IPC::MessageQueue::Unlink;
using Tools::TemporaryDirectory;

BOOST_AUTO_TEST_SUITE(IPC)
BOOST_AUTO_TEST_SUITE(MessageQueue)

BOOST_AUTO_TEST_SUITE(OpenConfiguration_tests)

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(OpenConfigurationConstructsWithNameAndIntegerOperationFlag)
{
  const OpenConfiguration config {
    "/myqueue123",
    get_underlying_value(OperationFlags::send_and_receive)};

  BOOST_TEST(config.name() == "/myqueue123");
  BOOST_TEST(config.operation_flag() ==
    get_underlying_value(OperationFlags::send_and_receive));
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(ConstructsWithNameAndOperationFlag)
{
  TemporaryDirectory temp_dir {"temp"};
  const OpenConfiguration config {temp_dir.path(), OperationFlags::send_only};

  BOOST_TEST(config.name() == temp_dir.path());
  BOOST_TEST(config.operation_flag() ==
    get_underlying_value(OperationFlags::send_only));
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(AddAdditionalOperationOrsOperationFlag)
{
  TemporaryDirectory temp_dir {"temp"};
  OpenConfiguration config {temp_dir.path(), OperationFlags::receive_only};

  BOOST_TEST_REQUIRE(config.name() == temp_dir.path());
  BOOST_TEST_REQUIRE(config.operation_flag() ==
    get_underlying_value(OperationFlags::receive_only));

  config.add_additional_operation(AdditionalOperationFlags::nonblocking);

  BOOST_TEST(config.operation_flag() !=
    get_underlying_value(OperationFlags::receive_only));

  BOOST_TEST((config.operation_flag() |
    get_underlying_value(OperationFlags::receive_only)));

  BOOST_TEST((config.operation_flag() |
    get_underlying_value(AdditionalOperationFlags::nonblocking)));

  BOOST_TEST(!(config.operation_flag() &
    get_underlying_value(AdditionalOperationFlags::create)));

  BOOST_TEST((config.operation_flag() |
    get_underlying_value(AdditionalOperationFlags::create)));

  BOOST_TEST((config.operation_flag() |
    get_underlying_value(AdditionalOperationFlags::exclusive_existence)));

  // cf. https://stackoverflow.com/questions/18591924/how-to-use-bitmask
  // http://www.dylanleigh.net/notes/c-cpp-tips/
  // Test for a flag. AND with the bitmask before testing with ==.

  BOOST_TEST((config.operation_flag() &
    get_underlying_value(OperationFlags::receive_only)) ==
      get_underlying_value(OperationFlags::receive_only));

  BOOST_TEST((config.operation_flag() &
    get_underlying_value(AdditionalOperationFlags::nonblocking)) ==
      get_underlying_value(AdditionalOperationFlags::nonblocking));

  BOOST_TEST((config.operation_flag() &
    get_underlying_value(AdditionalOperationFlags::create)) !=
      get_underlying_value(AdditionalOperationFlags::create));

  // Test for multiple flags. OR the bitmasks.
  BOOST_TEST((config.operation_flag() &
    (get_underlying_value(OperationFlags::receive_only) |
      get_underlying_value(AdditionalOperationFlags::nonblocking))) ==
        (get_underlying_value(OperationFlags::receive_only) |
          get_underlying_value(AdditionalOperationFlags::nonblocking)));
}

BOOST_AUTO_TEST_SUITE_END() // OpenConfiguration_tests

BOOST_AUTO_TEST_SUITE(NoAttributesOpen_tests)

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(ConstructsWithOpenConfiguration)
{
  TemporaryDirectory temp_dir {"temp"};
  OpenConfiguration config {temp_dir.path(), OperationFlags::send_and_receive};

  NoAttributesOpen open_object {config};

  BOOST_TEST(open_object.configuration().name() == temp_dir.path());
  BOOST_TEST(open_object.configuration().operation_flag() ==
    get_underlying_value(OperationFlags::send_and_receive));
  BOOST_TEST(!static_cast<bool>(open_object.message_queue_descriptor()));
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(CallOperatorFailsToOpenQueueWithoutCreateFlag)
{
  TemporaryDirectory temp_dir {"temp"};
  OpenConfiguration config {temp_dir.path(), OperationFlags::send_and_receive};

  NoAttributesOpen open_object {config};

  BOOST_TEST_REQUIRE(open_object.configuration().name() == temp_dir.path());
  BOOST_TEST_REQUIRE(open_object.configuration().operation_flag() ==
    get_underlying_value(OperationFlags::send_and_receive));
  BOOST_TEST_REQUIRE(
    !static_cast<bool>(open_object.message_queue_descriptor()));

  auto result = open_object();

  BOOST_TEST(static_cast<bool>(result.first));
  BOOST_TEST(!static_cast<bool>(result.second));
  BOOST_TEST(!static_cast<bool>(open_object.message_queue_descriptor()));
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(CallOperatorFailsToOpenQueueWithCreateFlag)
{
  TemporaryDirectory temp_dir {"temp"};
  OpenConfiguration config {temp_dir.path(), OperationFlags::send_and_receive};
  config.add_additional_operation(AdditionalOperationFlags::create);

  NoAttributesOpen open_object {config};

  BOOST_TEST_REQUIRE(open_object.configuration().name() == temp_dir.path());
  BOOST_TEST_REQUIRE(
    !static_cast<bool>(open_object.message_queue_descriptor()));

  auto result = open_object();

  BOOST_TEST(static_cast<bool>(result.first));
  BOOST_TEST(!static_cast<bool>(result.second));
  BOOST_TEST(!static_cast<bool>(open_object.message_queue_descriptor()));

  //auto close_result = Close()(*(open_object.message_queue_descriptor()));
  //BOOST_TEST(!static_cast<bool>(close_result));
  //auto unlink_result = Unlink()(open_object.configuration().name());
  //BOOST_TEST(!static_cast<bool>(unlink_result));
}

BOOST_AUTO_TEST_SUITE_END() // NoAttributesOpen_tests

BOOST_AUTO_TEST_SUITE(CreateOrOpen_tests)

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(CreateOrOpenCreatesNewMessageQueue)
{
  {
    // Name of the POSIX object referencing the queue.
    const std::string message_queue_object_name {"/myqueue123"};

    // Max length of a message (just for this process)
    constexpr long maximum_message_length {70};

    const int operation_flag {
      get_underlying_value(OperationFlags::send_and_receive) ||
        get_underlying_value(AdditionalOperationFlags::create) ||
        get_underlying_value(AdditionalOperationFlags::exclusive_existence)};

    /*
    CreateOrOpen create_q {
      message_queue_object_name,
      operation_flag,
      get_underlying_value(ModePermissions::user_rwx)};

    auto result = create_q(true);
    BOOST_TEST(!(static_cast<bool>(result.first)));
    BOOST_TEST((*(result.second)) > -1);

    std::cout <<
      "\n\n CreateOrOpenCreatesNewMessageQueue: message queue descriptor: " <<
        *(result.second) << "\n";
    */
  }
}

BOOST_AUTO_TEST_SUITE_END() // CreateOrOpen_tests
BOOST_AUTO_TEST_SUITE_END() // MessageQueue
BOOST_AUTO_TEST_SUITE_END() // IPC

max_stars_repo_name: ernestyalumni/HrdwCCppCUDA

max_issues_repo_name: ernestyalumni/HrdwCCppCUDA

max_forks_repo_name: ernestyalumni/HrdwCCppCUDA


text:
///////////////////////////////////////////////////////////////////////////////
// cells.hpp                                                                 //
//                                                                           //
//  Copyright 2010 Erwann Rogard. 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_STATISTICS_DETAIL_NON_PARAMETRIC_CONTINGENCY_TABLE_CELLS_CELLS_HPP_ER_2010
#define BOOST_STATISTICS_DETAIL_NON_PARAMETRIC_CONTINGENCY_TABLE_CELLS_CELLS_HPP_ER_2010
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_const.hpp>

#include <boost/math/policies/policy.hpp>

#include <boost/fusion/include/at_key.hpp>
#include <boost/fusion/container/map/detail/extract_keys.hpp> // needed?
#include <boost/fusion/container/map/detail/subset_traits.hpp>
#include <boost/fusion/container/map/detail/hashable_map.hpp>

#include <boost/unordered_map.hpp>

#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/parameters/accumulator.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/framework/parameters/weight.hpp>
#include <boost/accumulators/framework/detail/unpack_depends_on.hpp>
#include <boost/accumulators/framework/detail/parameters/policy.hpp>

#include <boost/statistics/detail/non_parametric/contingency_table/detail/raise_domain_error.hpp>
#include <boost/statistics/detail/non_parametric/contingency_table/factor/levels.hpp>
#include <boost/statistics/detail/non_parametric/contingency_table/factor/vec_levels.hpp>
#include <boost/statistics/detail/non_parametric/contingency_table/factor/domain_error_logger.hpp>
#include <boost/statistics/detail/non_parametric/contingency_table/factor/check_against_domain.hpp>

// Usage:
//  typedef cells<mpl::vector<X,Y,Z> > cells_
// This is a Boost.Accumulator feature specifying a contingency table asso-
// ciated with variables X, Y, and Z.

namespace boost {
namespace statistics{
namespace detail{
namespace contingency_table{
namespace cells_aux{

   template<typename Keys>
   struct depends_on{
        typedef typename contingency_table::vec_levels<Keys>::type vec_levels_;
        typedef typename boost::accumulators::detail::unpack_depends_on<
            vec_levels_
        >::type type;
   };

    template<typename T,typename Keys>
    struct traits{
        typedef boost::fusion::detail::map_subset_traits<T,Keys> inner_traits;
        typedef typename inner_traits::map subsample_;
        typedef boost::fusion::detail::hashable_map<
            subsample_> hashable_subsample_;
        typedef typename boost::unordered_map<
            hashable_subsample_,std::size_t> map_;

    };
}// cells_aux
namespace impl{

    template<typename T,typename Keys>
    class cells : public boost::accumulators::accumulator_base{
        typedef boost::accumulators::dont_care dont_care_;
        typedef std::size_t size_;

        typedef contingency_table::cells_aux::traits<T,Keys> traits_;
        typedef typename traits_::hashable_subsample_ hashable_subsample_;
        typedef typename traits_::map_ map_;

        public:

        typedef T 		sample_type;
        typedef size_ 	size_type;

        typedef map_& result_type; // not const bec map[] is non-const

        cells(dont_care_){}

        //template<typename A1,typename A2>
        //void operator()(const A1& a1,const A2& a2){
        //
        //}

        template<typename Args>
        void operator()(const Args& args){
            typedef boost::math::policies::policy<> pol_;
            this->update_if(
                hashable_subsample_( args[ boost::accumulators::sample ] ),
                args[ boost::accumulators::accumulator ],
                args[ boost::accumulators::detail::_policy |  pol_() ],
                args[ boost::accumulators::weight ]
            );
        }

        result_type result(dont_care_)const{
            return this->map;
        }

		private:
        template<typename V,typename N>
        void update(
            const V& s,
            const N& size
        ){
            ( this->map )[ s ] += size;
        }

        typedef ::boost::math::policies::domain_error<
             boost::math::policies::ignore_error
        > ignore_policy_;
        template<typename V,typename A,typename N>
        void update_if(
            const V& s,
            const A& acc,
            const ignore_policy_& policy,
            const N& size
        ){
            this->update(s,acc,size);
        }

        template<typename V,typename A,typename P,typename N>
        void update_if(
            const V& s,
            const A& acc,
            const P& policy,
            const N& size
        ){
            namespace ct = contingency_table;
            this->error_logger.reset();
            boost::fusion::for_each(
                s,
                ct::make_check_against_domain( acc, this->error_logger)
            );
            if(!this->error_logger.is_error())
            {
                this->update( s, size );
            }else{
                static const char* fun = "impl::cells::update_if %1%";
                ct::raise_domain_error<V>(
                  fun,
                  this->error_logger().c_str(),
                  policy
                );
            }
        }

        mutable map_ map;
        typedef contingency_table::domain_error_logger error_logger_;
        error_logger_ error_logger;
	};

}// impl
namespace tag
{

    template<typename Keys>
    struct cells
        : contingency_table::cells_aux::depends_on<Keys>::type
    {
        typedef typename contingency_table::par_spec< Keys >::type par_spec_;

        struct impl{
            template<typename T,typename W>
            struct apply{
        		typedef contingency_table::impl::cells<T,Keys> type;
            };
        };
    };

}// tag
namespace result_of{
namespace extract{

    template<typename Keys,typename AccSet>
    struct cells
    : boost::accumulators::detail::extractor_result<
        AccSet,
        contingency_table::tag::cells<Keys>
    >{};

}// extract
}// result_of
namespace extract
{
  	template<typename Keys,typename AccSet>
    typename contingency_table::result_of::extract::template
        cells<Keys,AccSet>::type
  	cells(AccSet const& acc)
    {
    	typedef contingency_table::tag::cells<Keys> the_tag;
        return boost::accumulators::extract_result<the_tag>(acc);
  	}

}// extract

using extract::cells;

}// contingency_table
}// detail
}// statistics
}// boost

#endif


text:
#include <iostream>
#include <unordered_map>
#include <string>
#include <vector>
#include <boost/functional/hash.hpp>

using namespace std;

#define DEBUG 0

#define MAX_W 100
#define MAX_L 100

typedef tuple<int, int, int, int> quad;
template<> struct hash<quad> {
  size_t operator()(const quad& q) const noexcept {
    size_t seed = 0;
    boost::hash_combine(seed, get<0>(q));
    boost::hash_combine(seed, get<1>(q));
    boost::hash_combine(seed, get<2>(q));
    boost::hash_combine(seed, get<3>(q));
    return seed;
  }
};

class AvoidRoads {
private:
  long dp[MAX_W+1][MAX_L+1] = { 0 };
  unordered_map<quad, int>bad_m;

public:
  long numWays(int w, int l, vector<string> bad) {
    preparebad(bad);

    dp[0][0] = 1;

    // Initialize bottom row
    for (int i = 1; i < w + 1; ++i) {
      quad p = make_tuple(i - 1, 0, i, 0);
      if (bad_m.find(p) == bad_m.end()) {
        dp[i][0] = dp[i-1][0];
      }
      int j = 0;
      // cout << "i: " << i << ", j: " << j << ", dp[i][j]: " << dp[i][j] << endl;
    }
    // Initialize left column
    for (int j = 1; j < l + 1; ++j) {
      quad p = make_tuple(0, j - 1, 0, j);
      if (bad_m.find(p) == bad_m.end()) {
        dp[0][j] = dp[0][j-1];
      }
      int i = 0;
      // cout << "i: " << i << ", j: " << j << ", dp[i][j]: " << dp[i][j] << endl;
    }
    for (int i = 1; i < w + 1; ++i) {
      for (int j = 1; j < l + 1; ++j) {
        if (bad_m.find(make_tuple(i - 1, j, i, j)) == bad_m.end()) {
          dp[i][j] += dp[i-1][j];
        }
        if (bad_m.find(make_tuple(i, j - 1, i, j)) == bad_m.end()) {
          dp[i][j] += dp[i][j-1];
        }
        // cout << "i: " << i << ", j: " << j << ", dp[i][j]: " << dp[i][j] << endl;
      }
    }

    // Only for debug
    // printf("\n");
    // for (int j = l; j >= 0; --j) {
    //   for (int i = 0; i < w + 1; ++i) {
    //     printf("%5ld", dp[i][j]);
    //   }
    //   printf("\n");
    // }
    return dp[w][l];
  }

  void preparebad(vector<string> bad) {
    for(auto &s : bad) {
      // NOTE: read int from bad string
      int l = s.size();
      vector<int> space;
      for (int i = 0; i < l; ++i) {
        if (s[i] == ' ') {
          space.push_back(i);
        }
      }

      vector<int> pos_list;
      pos_list.push_back(stoi(s));
      for(auto &p : space) {
        pos_list.push_back(stoi(s.substr(p + 1)));
      }

      quad p;
      if (pos_list[0] < pos_list[2] || pos_list[1] < pos_list[3]) {
        p = make_tuple(pos_list[0], pos_list[1], pos_list[2], pos_list[3]);
      } else {
        p = make_tuple(pos_list[2], pos_list[3], pos_list[0], pos_list[1]);
      }
      bad_m[p] = 1;
    }
  }
};

int main(int argc, char** argv) {
  AvoidRoads a0;
  vector<string> bad0 = {"0 0 0 1", "6 6 5 6"};
  std::cout << "a0: Expected 252, Got " << a0.numWays(6, 6, bad0) << "" << std::endl;

  AvoidRoads a1;
  vector<string> bad1 = {};
  std::cout << "a1: Expected 2, Got " << a1.numWays(1, 1, bad1) << "" << std::endl;

  AvoidRoads a2;
  vector<string> bad2 = {};
  std::cout << "a1: Expected 6406484391866534976, Got " << a2.numWays(35, 31, bad2) << "" << std::endl;

  AvoidRoads a3;
  vector<string> bad3 = {"0 0 1 0", "1 2 2 2", "1 1 2 1"};
  std::cout << "a1: Expected 0, Got " << a3.numWays(2, 2, bad3) << "" << std::endl;

  return 0;
}


text:
// Copyright 2015-2019 Hans Dembinski
//
// 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 <benchmark/benchmark.h>
#include <boost/histogram/axis.hpp>
#include <boost/histogram/axis/traits.hpp>
#include <boost/histogram/detail/axes.hpp>
#include <boost/mp11/algorithm.hpp>
#include <tuple>
#include <type_traits>
#include <vector>
#include "../test/throw_exception.hpp"
#include "generator.hpp"

#include <boost/assert.hpp>
struct assert_check {
  assert_check() {
    BOOST_ASSERT(false); // don't run with asserts enabled
  }
} _;

using namespace boost::histogram;
using reg = axis::regular<>;
using integ = axis::integer<>;
using var = axis::variable<>;
using vector_of_variant = std::vector<axis::variant<reg, integ, var>>;

template <class T, class U>
auto make_storage(const U& axes) {
  return std::vector<T>(detail::bincount(axes), 0);
}

template <class T>
auto make_strides(const T& axes) {
  std::vector<std::size_t> strides(detail::axes_rank(axes) + 1, 1);
  auto sit = strides.begin();
  detail::for_each_axis(axes, [&](const auto& a) { *++sit *= axis::traits::extent(a); });
  return strides;
}

template <class Axes, class Storage, class Tuple>
void fill_b(const Axes& axes, Storage& storage, const Tuple& t) {
  using namespace boost::mp11;
  std::size_t stride = 1, index = 0;
  mp_for_each<mp_iota<mp_size<Tuple>>>([&](auto i) {
    const auto& a = boost::histogram::detail::axis_get<i>(axes);
    const auto& v = std::get<i>(t);
    index += (a.index(v) + 1) * stride;
    stride *= axis::traits::extent(a);
  });
  ++storage[index];
}

template <class Axes, class Storage, class Tuple>
void fill_c(const Axes& axes, const std::size_t* strides, Storage& storage,
            const Tuple& t) {
  using namespace boost::mp11;
  std::size_t index = 0;
  assert(boost::histogram::detail::axes_rank(axes) ==
         boost::histogram::detail::axes_rank(t));
  mp_for_each<mp_iota<mp_size<Tuple>>>([&](auto i) {
    const auto& a = boost::histogram::detail::axis_get<i>(axes);
    const auto& v = std::get<i>(t);
    index += (a.index(v) + 1) * *strides++;
  });
  ++storage[index];
}

template <class T, class Distribution>
static void fill_1d_a(benchmark::State& state) {
  auto axes = std::make_tuple(reg(100, 0, 1));
  generator<Distribution> gen;
  auto storage = make_storage<T>(axes);
  for (auto _ : state) {
    const auto i = std::get<0>(axes).index(gen());
    ++storage[i + 1];
  }
}

template <class T, class Distribution>
static void fill_1d_b(benchmark::State& state) {
  auto axes = std::make_tuple(reg(100, 0, 1));
  generator<Distribution> gen;
  auto storage = make_storage<T>(axes);
  for (auto _ : state) { fill_b(axes, storage, std::forward_as_tuple(gen())); }
}

template <class T, class Distribution>
static void fill_1d_c(benchmark::State& state) {
  auto axes = std::make_tuple(reg(100, 0, 1));
  generator<Distribution> gen;
  auto storage = make_storage<T>(axes);
  auto strides = make_strides(axes);
  for (auto _ : state) {
    fill_c(axes, strides.data(), storage, std::forward_as_tuple(gen()));
  }
}

template <class T, class Distribution>
static void fill_1d_c_dyn(benchmark::State& state) {
  auto axes = vector_of_variant({reg(100, 0, 1)});
  generator<Distribution> gen;
  auto storage = make_storage<T>(axes);
  auto strides = make_strides(axes);
  for (auto _ : state) {
    fill_c(axes, strides.data(), storage, std::forward_as_tuple(gen()));
  }
}

template <class T, class Distribution>
static void fill_2d_a(benchmark::State& state) {
  auto axes = std::make_tuple(reg(100, 0, 1), reg(100, 0, 1));
  generator<Distribution> gen;
  auto storage = make_storage<T>(axes);
  for (auto _ : state) {
    const auto i0 = std::get<0>(axes).index(gen());
    const auto i1 = std::get<1>(axes).index(gen());
    const auto stride = axis::traits::extent(std::get<0>(axes));
    ++storage[(i0 + 1) * stride + (i1 + 1)];
  }
}

template <class T, class Distribution>
static void fill_2d_b(benchmark::State& state) {
  auto axes = std::make_tuple(reg(100, 0, 1), reg(100, 0, 1));
  generator<Distribution> gen;
  auto storage = make_storage<T>(axes);
  for (auto _ : state) { fill_b(axes, storage, std::forward_as_tuple(gen(), gen())); }
}

template <class T, class Distribution>
static void fill_2d_c(benchmark::State& state) {
  auto axes = std::make_tuple(reg(100, 0, 1), reg(100, 0, 1));
  generator<Distribution> gen;
  auto storage = make_storage<T>(axes);
  auto strides = make_strides(axes);
  assert(strides.size() == 3);
  assert(strides[0] == 1);
  assert(strides[1] == 102);
  for (auto _ : state) {
    fill_c(axes, strides.data(), storage, std::forward_as_tuple(gen(), gen()));
  }
}

template <class T, class Distribution>
static void fill_2d_c_dyn(benchmark::State& state) {
  auto axes = vector_of_variant({reg(100, 0, 1), reg(100, 0, 1)});
  generator<Distribution> gen;
  auto storage = make_storage<T>(axes);
  auto strides = make_strides(axes);
  assert(strides.size() == 3);
  assert(strides[0] == 1);
  assert(strides[1] == 102);
  for (auto _ : state) {
    fill_c(axes, strides.data(), storage, std::forward_as_tuple(gen(), gen()));
  }
}

BENCHMARK_TEMPLATE(fill_1d_a, int, uniform);
BENCHMARK_TEMPLATE(fill_1d_a, double, uniform);
BENCHMARK_TEMPLATE(fill_1d_b, double, uniform);
BENCHMARK_TEMPLATE(fill_1d_c, double, uniform);
BENCHMARK_TEMPLATE(fill_1d_c_dyn, double, uniform);
BENCHMARK_TEMPLATE(fill_2d_a, double, uniform);
BENCHMARK_TEMPLATE(fill_2d_b, double, uniform);
BENCHMARK_TEMPLATE(fill_2d_c, double, uniform);
BENCHMARK_TEMPLATE(fill_2d_c_dyn, double, uniform);

BENCHMARK_TEMPLATE(fill_1d_a, double, normal);
BENCHMARK_TEMPLATE(fill_1d_b, double, normal);
BENCHMARK_TEMPLATE(fill_1d_c, double, normal);
BENCHMARK_TEMPLATE(fill_2d_a, double, normal);
BENCHMARK_TEMPLATE(fill_2d_b, double, normal);
BENCHMARK_TEMPLATE(fill_2d_c, double, normal);


text:
/***************************************************************************
 *   Copyright (C) 2008-2021 by Andrzej Rybczak                            *
 *   andrzej@rybczak.net                                                   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program 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 General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.              *
 ***************************************************************************/

#include "tags.h"

#ifdef HAVE_TAGLIB_H

// taglib includes
#include <id3v1tag.h>
#include <id3v2tag.h>
#include <fileref.h>
#include <flacfile.h>
#include <mpegfile.h>
#include <vorbisfile.h>
#include <opusfile.h>
#include <tag.h>
#include <textidentificationframe.h>
#include <commentsframe.h>
#include <xiphcomment.h>

#include <boost/filesystem.hpp>
#include "global.h"
#include "settings.h"
#include "utility/string.h"
#include "utility/wide_string.h"

namespace {

TagLib::StringList tagList(const MPD::MutableSong &s, MPD::Song::GetFunction f)
{
	TagLib::StringList result;
	unsigned idx = 0;
	for (std::string value; !(value = (s.*f)(idx)).empty(); ++idx)
		result.append(ToWString(value));
	return result;
}

void readCommonTags(mpd_song *s, TagLib::Tag *tag)
{
	Tags::setAttribute(s, "Title", tag->title().to8Bit(true));
	Tags::setAttribute(s, "Artist", tag->artist().to8Bit(true));
	Tags::setAttribute(s, "Album", tag->album().to8Bit(true));
	Tags::setAttribute(s, "Date", boost::lexical_cast<std::string>(tag->year()));
	Tags::setAttribute(s, "Track", boost::lexical_cast<std::string>(tag->track()));
	Tags::setAttribute(s, "Genre", tag->genre().to8Bit(true));
	Tags::setAttribute(s, "Comment", tag->comment().to8Bit(true));
}

void readID3v1Tags(mpd_song *s, TagLib::ID3v1::Tag *tag)
{
	readCommonTags(s, tag);
}

void readID3v2Tags(mpd_song *s, TagLib::ID3v2::Tag *tag)
{
	auto readFrame = [s](const TagLib::ID3v2::FrameList &fields, const char *name) {
		for (const auto &field : fields)
		{
			if (auto textFrame = dynamic_cast<TagLib::ID3v2::TextIdentificationFrame *>(field))
			{
				auto values = textFrame->fieldList();
				for (const auto &value : values)
					Tags::setAttribute(s, name, value.to8Bit(true));
			}
			else
				Tags::setAttribute(s, name, field->toString().to8Bit(true));
		}
	};
	auto &frames = tag->frameListMap();
	readFrame(frames["TIT2"], "Title");
	readFrame(frames["TPE1"], "Artist");
	readFrame(frames["TPE2"], "AlbumArtist");
	readFrame(frames["TALB"], "Album");
	readFrame(frames["TDRC"], "Date");
	readFrame(frames["TRCK"], "Track");
	readFrame(frames["TCON"], "Genre");
	readFrame(frames["TCOM"], "Composer");
	readFrame(frames["TPE4"], "Performer");
	readFrame(frames["TPOS"], "Disc");
	readFrame(frames["COMM"], "Comment");
}

void readXiphComments(mpd_song *s, TagLib::Ogg::XiphComment *tag)
{
	auto readField = [s](const TagLib::StringList &fields, const char *name) {
		for (const auto &field : fields)
			Tags::setAttribute(s, name, field.to8Bit(true));
	};
	auto &fields = tag->fieldListMap();
	readField(fields["TITLE"], "Title");
	readField(fields["ARTIST"], "Artist");
	readField(fields["ALBUMARTIST"], "AlbumArtist");
	readField(fields["ALBUM"], "Album");
	readField(fields["DATE"], "Date");
	readField(fields["TRACKNUMBER"], "Track");
	readField(fields["GENRE"], "Genre");
	readField(fields["COMPOSER"], "Composer");
	readField(fields["PERFORMER"], "Performer");
	readField(fields["DISCNUMBER"], "Disc");
	readField(fields["COMMENT"], "Comment");
}

void writeCommonTags(const MPD::MutableSong &s, TagLib::Tag *tag)
{
	tag->setTitle(ToWString(s.getTitle()));
	tag->setArtist(ToWString(s.getArtist()));
	tag->setAlbum(ToWString(s.getAlbum()));
	try {
		tag->setYear(boost::lexical_cast<TagLib::uint>(s.getDate()));
	} catch (boost::bad_lexical_cast &) {
		std::cerr << "writeCommonTags: couldn't write 'year' tag to '" << s.getURI() << "' as it's not a positive integer\n";
	}
	try {
		tag->setTrack(boost::lexical_cast<TagLib::uint>(s.getTrack()));
	} catch (boost::bad_lexical_cast &) {
		std::cerr << "writeCommonTags: couldn't write 'track' tag to '" << s.getURI() << "' as it's not a positive integer\n";
	}
	tag->setGenre(ToWString(s.getGenre()));
	tag->setComment(ToWString(s.getComment()));
}

void writeID3v2Tags(const MPD::MutableSong &s, TagLib::ID3v2::Tag *tag)
{
	auto writeID3v2 = [&](const TagLib::ByteVector &type, const TagLib::StringList &list) {
		tag->removeFrames(type);
		if (!list.isEmpty())
		{
			if (type == "COMM") // comment needs to be handled separately
			{
				auto frame = new TagLib::ID3v2::CommentsFrame(TagLib::String::UTF8);
				// apparently there can't be multiple comments,
				// so if there is more than one, join them.
				frame->setText(join(list, TagLib::String(MPD::Song::TagsSeparator, TagLib::String::UTF8)));
				tag->addFrame(frame);
			}
			else
			{
				auto frame = new TagLib::ID3v2::TextIdentificationFrame(type, TagLib::String::UTF8);
				frame->setText(list);
				tag->addFrame(frame);
			}
		}
	};
	writeID3v2("TIT2", tagList(s, &MPD::Song::getTitle));
	writeID3v2("TPE1", tagList(s, &MPD::Song::getArtist));
	writeID3v2("TPE2", tagList(s, &MPD::Song::getAlbumArtist));
	writeID3v2("TALB", tagList(s, &MPD::Song::getAlbum));
	writeID3v2("TDRC", tagList(s, &MPD::Song::getDate));
	writeID3v2("TRCK", tagList(s, &MPD::Song::getTrack));
	writeID3v2("TCON", tagList(s, &MPD::Song::getGenre));
	writeID3v2("TCOM", tagList(s, &MPD::Song::getComposer));
	writeID3v2("TPE4", tagList(s, &MPD::Song::getPerformer));
	writeID3v2("TPOS", tagList(s, &MPD::Song::getDisc));
	writeID3v2("COMM", tagList(s, &MPD::Song::getComment));
}

void writeXiphComments(const MPD::MutableSong &s, TagLib::Ogg::XiphComment *tag)
{
	auto writeXiph = [&](const TagLib::String &type, const TagLib::StringList &list) {
		for (auto it = list.begin(); it != list.end(); ++it)
			tag->addField(type, *it, it == list.begin());
	};
	// remove field previously used as album artist
	tag->removeFields("ALBUM ARTIST");
	// remove field TRACK, some taggers use it as TRACKNUMBER
	tag->removeFields("TRACK");
	// remove field DISC, some taggers use it as DISCNUMBER
	tag->removeFields("DISC");
	// remove field DESCRIPTION, it's displayed as COMMENT
	tag->removeFields("DESCRIPTION");
	writeXiph("TITLE", tagList(s, &MPD::Song::getTitle));
	writeXiph("ARTIST", tagList(s, &MPD::Song::getArtist));
	writeXiph("ALBUMARTIST", tagList(s, &MPD::Song::getAlbumArtist));
	writeXiph("ALBUM", tagList(s, &MPD::Song::getAlbum));
	writeXiph("DATE", tagList(s, &MPD::Song::getDate));
	writeXiph("TRACKNUMBER", tagList(s, &MPD::Song::getTrack));
	writeXiph("GENRE", tagList(s, &MPD::Song::getGenre));
	writeXiph("COMPOSER", tagList(s, &MPD::Song::getComposer));
	writeXiph("PERFORMER", tagList(s, &MPD::Song::getPerformer));
	writeXiph("DISCNUMBER", tagList(s, &MPD::Song::getDisc));
	writeXiph("COMMENT", tagList(s, &MPD::Song::getComment));
}

Tags::ReplayGainInfo getReplayGain(TagLib::Ogg::XiphComment *tag)
{
	auto first_or_empty = [](const TagLib::StringList &list) {
		std::string result;
		if (!list.isEmpty())
			result = list.front().to8Bit(true);
		return result;
	};
	auto &fields = tag->fieldListMap();
	return Tags::ReplayGainInfo(
		first_or_empty(fields["REPLAYGAIN_REFERENCE_LOUDNESS"]),
		first_or_empty(fields["REPLAYGAIN_TRACK_GAIN"]),
		first_or_empty(fields["REPLAYGAIN_TRACK_PEAK"]),
		first_or_empty(fields["REPLAYGAIN_ALBUM_GAIN"]),
		first_or_empty(fields["REPLAYGAIN_ALBUM_PEAK"])
	);
}

}

namespace Tags {

void setAttribute(mpd_song *s, const char *name, const std::string &value)
{
	mpd_pair pair = { name, value.c_str() };
	mpd_song_feed(s, &pair);
}

bool extendedSetSupported(const TagLib::File *f)
{
	return dynamic_cast<const TagLib::MPEG::File *>(f)
	||     dynamic_cast<const TagLib::Ogg::Vorbis::File *>(f)
	||     dynamic_cast<const TagLib::Ogg::Opus::File *>(f)
	||     dynamic_cast<const TagLib::FLAC::File *>(f);
}

ReplayGainInfo readReplayGain(TagLib::File *f)
{
	ReplayGainInfo result;
	if (auto vorbis_file = dynamic_cast<TagLib::Ogg::Vorbis::File *>(f))
	{
		if (auto xiph = vorbis_file->tag())
			result = getReplayGain(xiph);
	}
	else if (auto opus_file = dynamic_cast<TagLib::Ogg::Opus::File *>(f))
	{
		if (auto xiph = opus_file->tag())
			result = getReplayGain(xiph);
	}
	else if (auto flac_file = dynamic_cast<TagLib::FLAC::File *>(f))
	{
		if (auto xiph = flac_file->xiphComment())
			result = getReplayGain(xiph);
	}
	return result;
}

void read(mpd_song *s)
{
	TagLib::FileRef f(mpd_song_get_uri(s));
	if (f.isNull())
		return;

	setAttribute(s, "Time", boost::lexical_cast<std::string>(f.audioProperties()->length()));

	if (auto mpeg_file = dynamic_cast<TagLib::MPEG::File *>(f.file()))
	{
		// prefer id3v2 only if available
		if (auto id3v2 = mpeg_file->ID3v2Tag())
			readID3v2Tags(s, id3v2);
		else if (auto id3v1 = mpeg_file->ID3v1Tag())
			readID3v1Tags(s, id3v1);
	}
	else if (auto vorbis_file = dynamic_cast<TagLib::Ogg::Vorbis::File *>(f.file()))
	{
		if (auto xiph = vorbis_file->tag())
			readXiphComments(s, xiph);
	}
	else if (auto opus_file = dynamic_cast<TagLib::Ogg::Opus::File *>(f.file()))
	{
		if (auto xiph = opus_file->tag())
			readXiphComments(s, xiph);
	}
	else if (auto flac_file = dynamic_cast<TagLib::FLAC::File *>(f.file()))
	{
		if (auto xiph = flac_file->xiphComment())
			readXiphComments(s, xiph);
	}
	else
		readCommonTags(s, f.tag());
}

bool write(MPD::MutableSong &s)
{
	std::string old_name;
	if (s.isFromDatabase())
		old_name += Config.mpd_music_dir;
	old_name += s.getURI();

	TagLib::FileRef f(old_name.c_str());
	if (f.isNull())
		return false;

	bool saved = false;
	if (auto mpeg_file = dynamic_cast<TagLib::MPEG::File *>(f.file()))
	{
		writeID3v2Tags(s, mpeg_file->ID3v2Tag(true));
		// write id3v2.4 tags only
		if (!mpeg_file->save(TagLib::MPEG::File::ID3v2, true, 4, false))
			return false;
		// do not call generic save() as it will duplicate tags
		saved = true;
	}
	else if (auto vorbis_file = dynamic_cast<TagLib::Ogg::Vorbis::File *>(f.file()))
	{
		writeXiphComments(s, vorbis_file->tag());
	}
	else if (auto opus_file = dynamic_cast<TagLib::Ogg::Opus::File *>(f.file()))
	{
		writeXiphComments(s, opus_file->tag());
	}
	else if (auto flac_file = dynamic_cast<TagLib::FLAC::File *>(f.file()))
	{
		writeXiphComments(s, flac_file->xiphComment(true));
	}
	else
		writeCommonTags(s, f.tag());

	if (!saved && !f.save())
		return false;

	// TODO: move this somewhere else
	if (!s.getNewName().empty())
	{
		std::string new_name;
		if (s.isFromDatabase())
			new_name += Config.mpd_music_dir;
		new_name += s.getDirectory();
		new_name += "/";
		new_name += s.getNewName();
		boost::filesystem::rename(old_name, new_name);
	}
	return true;
}

}

#endif // HAVE_TAGLIB_H

max_stars_repo_name: doctorfree/mpcplus

max_issues_repo_name: doctorfree/mpcplus

max_forks_repo_name: doctorfree/mpcplus


text:
/**
 * Copyright (C) 2016-2019 Xilinx, Inc
 * Author(s): Ch Vamshi Krishna
 *          : Hemant Kashyap
 * ZNYQ HAL sw_emu Driver layered on top of ZYNQ hardware driver
 *
 * Licensed under the Apache License, Version 2.0 (the "License"). You may
 * not use this file except in compliance with the License. A copy of the
 * License is located 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.
 */

#include "pllauncher_defines.h"
#include <iostream>
#include <boost/property_tree/xml_parser.hpp>
#include "shim.h"
#include "shim-profile.h"
#include <cstring>
#include <errno.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <thread>

namespace ZYNQ {

namespace ZYNQ_HW_EM {
bool isRemotePortMapped = false;
void * remotePortMappedPointer = NULL;
namespace pt = boost::property_tree;

bool initRemotePortMap()
{
  int fd;
  unsigned addr;//, page_addr , page_offset;
  unsigned page_size = sysconf(_SC_PAGESIZE);

  fd = open("/dev/mem", O_RDWR);
  if (fd < 1) {
    std::cout << "Unable to open /dev/mem file" << std::endl;
    exit(-1);
  }

  addr = PL_RP_MP_ALLOCATED_ADD;

  //page_addr = (addr & ~(page_size - 1));
  //page_offset = addr - page_addr;

  remotePortMappedPointer = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
  MAP_SHARED, fd, (addr & ~(page_size - 1)));

  if (remotePortMappedPointer == MAP_FAILED) {
    std::cout << "Remote Port mapping to address " << addr << " Failed" << std::endl;
    exit(-1);
  }
  ZYNQ_HW_EM::isRemotePortMapped = true;
  return true;
}

bool validateXclBin(const xclBin *header , std::string &xclBinName)
{

  char *bitstreambin = reinterpret_cast<char*> (const_cast<xclBin*> (header));

    //int result = 0; Not used. Removed to get rid of compiler warning, and probably a Coverity CID.
    ssize_t zipFileSize = 0;
    ssize_t xmlFileSize = 0;
    ssize_t debugFileSize = 0;
    ssize_t memTopologySize = 0;

    char* xmlFile = nullptr;

    if ((!std::memcmp(bitstreambin, "xclbin0", 7)) || (!std::memcmp(bitstreambin, "xclbin1", 7)))
    {
      return false;
    }
    else if (!std::memcmp(bitstreambin,"xclbin2",7))
    {
      auto top = reinterpret_cast<const axlf*>(header);
      if (auto sec = xclbin::get_axlf_section(top,EMBEDDED_METADATA)) {
        xmlFileSize = sec->m_sectionSize;
        xmlFile = new char[xmlFileSize];
        memcpy(xmlFile, bitstreambin + sec->m_sectionOffset, xmlFileSize);
      }
    }
    else
    {
      return false;
    }

    if(!xmlFile)
    {
      return false;
    }

    pt::ptree xml_project;
    std::string sXmlFile;
    sXmlFile.assign(xmlFile,xmlFileSize);
    std::stringstream xml_stream;
    xml_stream<<sXmlFile;
    pt::read_xml(xml_stream,xml_project);

    // iterate platforms
    int count = 0;
    for (auto& xml_platform : xml_project.get_child("project"))
    {
      if (xml_platform.first != "platform")
        continue;
      if (++count>1)
      {
        //Give error and return from here
      }
    }

    // iterate devices
    count = 0;
    for (auto& xml_device : xml_project.get_child("project.platform"))
    {
      if (xml_device.first != "device")
        continue;
      if (++count>1)
      {
        //Give error and return from here
      }
    }

    // iterate cores
    count = 0;
    for (auto& xml_core : xml_project.get_child("project.platform.device"))
    {
      if (xml_core.first != "core")
        continue;
      if (++count>1)
      {
        //Give error and return from here
      }
    }
    xclBinName = xml_project.get<std::string>("project.<xmlattr>.name","");

    return true;

}
}

int ZYNQShim::xclLoadXclBin(const xclBin *header) {
  int ret = 0;
  if (mLogStream.is_open()) {
    mLogStream << __func__ << ", " << std::this_thread::get_id() << std::endl;
    mLogStream.close();
  }
  char *bitstreambin = reinterpret_cast<char*>(const_cast<xclBin*>(header));
  std::string xclBinName = "";
  if (!ZYNQ_HW_EM::isRemotePortMapped) {
    ZYNQ_HW_EM::initRemotePortMap();
  }
  ssize_t xmlFileSize = 0;
  char* xmlFile = nullptr;

  if ((!std::memcmp(bitstreambin, "xclbin0", 7)) || (!std::memcmp(bitstreambin, "xclbin1", 7))) {

	printf("ERROR: Legacy xclbins are no longer supported. \n");
    return 1;

  } else if (!std::memcmp(bitstreambin, "xclbin2", 7)) {
    auto top = reinterpret_cast<const axlf*>(header);
    if (auto sec = xclbin::get_axlf_section(top, EMBEDDED_METADATA)) {
      xmlFileSize = sec->m_sectionSize;
      xmlFile = new char[xmlFileSize + 1];
      memcpy(xmlFile, bitstreambin + sec->m_sectionOffset, xmlFileSize);
      xmlFile[xmlFileSize] = '\0';
    }
  } else {
    return 1;
  }

  if (!ZYNQ_HW_EM::validateXclBin(header, xclBinName)) {
    printf("ERROR:Xclbin validation failed\n");
    return 1;
  }

  xclBinName = xclBinName + ".xclbin";

  //Send the LoadXclBin
  PLLAUNCHER::OclCommand *cmd = new PLLAUNCHER::OclCommand();
  cmd->setCommand(PLLAUNCHER::PL_OCL_LOADXCLBIN_ID);
  cmd->addArg(xclBinName.c_str());
  uint32_t length;
  uint8_t* buff = cmd->generateBuffer(&length);
  for (unsigned int i = 0; i < length; i += 4) {
    uint32_t copySize = (length - i) > 4 ? 4 : length - i;
    memcpy(((char*) (ZYNQ_HW_EM::remotePortMappedPointer)) + i, buff + i, copySize);
  }

  //Send the end of packet
  char cPacketEndChar = PL_OCL_PACKET_END_MARKER;
  memcpy((char*) (ZYNQ_HW_EM::remotePortMappedPointer), &cPacketEndChar, 1);

	drm_zocl_axlf axlf_obj = { const_cast<axlf *>(header) };
	ret = ioctl(mKernelFD, DRM_IOCTL_ZOCL_READ_AXLF, &axlf_obj);

  return ret;
}

ZYNQShim::~ZYNQShim() {
  //Tell the Pllauncher to close
  if (ZYNQ_HW_EM::isRemotePortMapped) {
    PLLAUNCHER::OclCommand *cmd = new PLLAUNCHER::OclCommand();
    cmd->setCommand(PLLAUNCHER::PL_OCL_XRESET_ID);
    uint32_t iLength;
    memcpy((char*) (ZYNQ_HW_EM::remotePortMappedPointer), (char*) cmd->generateBuffer(&iLength),
        iLength);

    //Send the end of packet
    char cPacketEndChar = PL_OCL_PACKET_END_MARKER;
    memcpy((char*) (ZYNQ_HW_EM::remotePortMappedPointer), &cPacketEndChar, 1);
    delete cmd;
  }
  if (mKernelFD > 0) {
    close(mKernelFD);
  }
  if (mLogStream.is_open()) {
    mLogStream << __func__ << ", " << std::this_thread::get_id() << std::endl;
    mLogStream.close();
  }
}

}
unsigned int xclProbe() {
  return 1;
}
//end namespace ZYNQ


text:
#ifndef _NGX_CPPINC_HPP
#define _NGX_CPPINC_HPP

#if __cplusplus < 201103L
    #error "ngx_cpp_module need C++11 implementation!"
#endif

#include <cassert>

#include <string>
#include <deque>
#include <exception>

#include <boost/core/ignore_unused.hpp>
#include <boost/core/explicit_operator_bool.hpp>

#include <boost/type_traits.hpp>
#include <boost/noncopyable.hpp>
#include <boost/next_prior.hpp>
#include <boost/static_assert.hpp>
#include <boost/function.hpp>
//#include <boost/format.hpp>

#include <boost/algorithm/string.hpp>
#include <boost/exception/all.hpp>
#include <boost/functional/factory.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/mpl/logical.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/at.hpp>
#include <boost/tti/member_type.hpp>
#include <boost/tti/has_member_data.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/utility/string_ref.hpp>

#endif  // _NGX_CPPINC_HPP


text:
// Project Includes
#include "Exception.h"
#include "StringUtility.h"

// Boost Includes
#include <boost/locale.hpp>

//--------------------------------------------------------------------------------------------------
namespace Common
{

//--------------------------------------------------------------------------------------------------
std::wstring MultibyteToWide(const std::string & source)
{
    try
    {
        // Create locale generator
        // "" is the system default locale
        const boost::locale::generator gen;
        const std::locale locale = gen("");

        return boost::locale::conv::to_utf<wchar_t>(source, locale, boost::locale::conv::stop);
    }
    catch (boost::locale::conv::conversion_error &)
    {
        // AFAIK the boost::locale::conv::conversion_error doesn't contain any information at all
        // I assume that the only reason it can be thrown is because
        // Error - The source string contained at least once character that could not be converted using the default locale
        const std::string msg("The source string contained at least once character that could not be converted using the default locale");
        throw Common::Exception(__FILE__, __LINE__, msg);
    }
}

//--------------------------------------------------------------------------------------------------
std::string WideToMultibyte(const std::wstring & source)
{
    try
    {
        // Create locale generator
        // "" is the system default locale
        const boost::locale::generator gen;
        const std::locale locale = gen("");

        return boost::locale::conv::from_utf(source, locale, boost::locale::conv::stop);
    }
    catch (boost::locale::conv::conversion_error &)
    {
        // AFAIK the boost::locale::conv::conversion_error doesn't contain any information at all
        // I assume that the only reason it can be thrown is because
        // Error - The source string contained at least once character that could not be converted using the default locale
        const std::string msg("The source string contained at least once character that could not be converted using the default locale");
        throw Common::Exception(__FILE__, __LINE__, msg);
    }
}

//--------------------------------------------------------------------------------------------------
std::string ReplaceAllOccurances(const std::string & source, const std::string & a, const std::string & b)
{
    std::string result = source;
    size_t index = 0;

    while ( (index = result.find(a, index)) != std::string::npos)
    {
        result.replace(index, a.size(), b);
        index += b.size();
    }

    return result;
}

//--------------------------------------------------------------------------------------------------
std::wstring ReplaceAllOccurances(const std::wstring & source, const std::wstring & a, const std::wstring & b)
{
    std::wstring result = source;
    size_t index = 0;

    while ( (index = result.find(a, index)) != std::wstring::npos)
    {
        result.replace(index, a.size(), b);
        index += b.size();
    }

    return result;
}

//--------------------------------------------------------------------------------------------------
} // End namespace

max_stars_repo_name: ChristopherPisz/Common

max_issues_repo_name: ChristopherPisz/Common

max_forks_repo_name: ChristopherPisz/Common


text:
/*
 *   Copyright 2012      NVIDIA Corporation
 *
 *   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 "node.hpp"
#include <vector>
#include <memory>
#include <ostream>
#include <boost/iterator/indirect_iterator.hpp>

#include "type.hpp"
#include "monotype.hpp"
#include "ctype.hpp"

/*!
  \file   expression.hpp
  \brief  Contains the declarations for all AST expression nodes.

*/

namespace backend {

/*!
  \addtogroup nodes
  @{
 */

//! The super class for all AST expression nodes.
/*! Every expression bears a type and a ctype.  The type is a Copperhead
  type describing the interface the expression must have. The ctype
  is used during implementation to describe the C++ type used to
  implement the expression node.
*/
class expression
    : public node
{
protected:
    //! The Copperhead type of the expression
    std::shared_ptr<const type_t> m_type;
    //! The C++ implementation type of the expression
    std::shared_ptr<const ctype::type_t> m_ctype;
/*!
  The constructor is only intended to be called by subtypes.
  \param self A reference to the subtype object being constructed,
  necessary for disambiguating the underlying \p variant.
  \param type The Copperhead type of the expression, defaults to Void
  \param ctype The C++ type of the expression, defaults to void

*/
    template<typename Derived>
    expression(Derived &self,
               const std::shared_ptr<const type_t>& type = void_mt,
               const std::shared_ptr<const ctype::type_t>& ctype = ctype::void_mt)
        : node(self), m_type(type), m_ctype(ctype)
        {}
public:

    //! Gets the Copperhead type of the expression
    const type_t& type(void) const;
    //! Gets the C++ implementation type of the expression
    const ctype::type_t& ctype(void) const;
    /*! When we need to get at the pointer holding an expression */
    std::shared_ptr<const expression> ptr() const;

};

//! The parent class for all Literal expressions
class literal
    : public expression
{
protected:
    const std::string m_val;
public:
/*! This constructor is called from subclasses.

  \param self Reference to child being constructed.
  \param val Value of the literal.
  \param type Copperhead type.
  \param ctype C++ implementation type.
*/
    template<typename Derived>
    literal(Derived &self,
            const std::string& val,
            const std::shared_ptr<const type_t>& type = void_mt,
            const std::shared_ptr<const ctype::type_t>& ctype = ctype::void_mt)
        : expression(self, type, ctype), m_val(val)
        {}
    //! A constructor for standalone Literal expressions.
/*! \p literal can also be used on its own, with no subclass. This
  constructor facilitates this.

  \param val Value of the literal.
  \param type Copperhead type.
  \param ctype C++ implementation type.
*/
    literal(const std::string& val,
            const std::shared_ptr<const type_t>& type = void_mt,
            const std::shared_ptr<const ctype::type_t>& ctype = ctype::void_mt);

    //! Get the value of this literal
    const std::string& id(void) const;
    /*! When we need to get at the pointer holding a literal */
    std::shared_ptr<const literal> ptr() const;

};
//! AST node for identifiers.
class name
    : public literal
{
public:
/*!
  \param val The identifier text.
  \param type The Copperhead type.
  \param ctype The C++ implementation type.
*/
    name(const std::string &val,
         const std::shared_ptr<const type_t>& type = void_mt,
         const std::shared_ptr<const ctype::type_t>& ctype = ctype::void_mt);
//! Constructor for subclasses.
/*!
  \param self Reference to subclass being constructed.
  \param val The identifier text.
  \param type The Copperhead type.
  \param ctype The C++ implementation type.

  \return
*/
    template<typename Derived>
    name(Derived& self, const std::string &val,
         const std::shared_ptr<const type_t>& type,
         const std::shared_ptr<const ctype::type_t>& ctype) :
        literal(self, val, type, ctype) {}

    /*! When we need to get at the pointer holding a name */
    std::shared_ptr<const name> ptr() const;

};
//! AST node for tuples.
/*! We use tuples to represent any sequence of expressions in the
  program text.
*/

class tuple
    : public expression
{
public:
/*!
  \param values The sequence of expressions.
  \param type The Copperhead type for this tuple.
  \param ctype The C++ implementation type for this tuple.

  \return
*/
    tuple(std::vector<std::shared_ptr<const expression> > &&values,
          const std::shared_ptr<const type_t>& type = void_mt,
          const std::shared_ptr<const ctype::type_t>& ctype = ctype::void_mt);
protected:
    const std::vector<std::shared_ptr<const expression> > m_values;
public:
    //! A constant iterator to the expressions held by the tuple
    typedef decltype(boost::make_indirect_iterator(m_values.cbegin())) const_iterator;
    //! The iterator to the beginning of the expressions held by the tuple
    const_iterator begin() const;
    //! The iterator to the end of the expressions held by the tuple
    const_iterator end() const;

    //! The arity of this tuple.
/*!
  \return How many expressions are held by this tuple.
*/
    int arity() const;
    /*! When we need to get at the pointer holding a tuple */
    std::shared_ptr<const tuple> ptr() const;

};
//! AST node for applying a function to a sequence of arguments
class apply
    : public expression
{
protected:
    const std::shared_ptr<const name> m_fn;
    const std::shared_ptr<const tuple> m_args;
public:
/*!
  \param fn The function to be applied.
  \param args The arguments given to the function.
*/

    apply(const std::shared_ptr<const name> &fn,
          const std::shared_ptr<const tuple> &args);
    //! Get the function to be applied
    const name &fn(void) const;
    //! Get the arguments given to the function
    const tuple &args(void) const;
    /*! When we need to get at the pointer holding a apply */
    std::shared_ptr<const apply> ptr() const;

};

//! AST node for \p lambda expressions
/*! Anonymous function definition
 */
class lambda
    : public expression
{
protected:
    const std::shared_ptr<const tuple> m_args;
    const std::shared_ptr<const expression> m_body;
public:
    //! Constructor
/*!
  \param args Formal arguments of the \p lambda
  \param body Expression to be evaluated in the \p lambda
  \param type Copperhead type.
  \param ctype C++ implementation type.
*/

    lambda(const std::shared_ptr<const tuple> &args,
           const std::shared_ptr<const expression> &body,
           const std::shared_ptr<const type_t>& type = void_mt,
           const std::shared_ptr<const ctype::type_t>& ctype = ctype::void_mt);
    //! Get the formal arguments of the \p lambda
    const tuple &args(void) const;
    //! Get the expression to be evaluated in the \p lambda
    const expression &body(void) const;
    /*! When we need to get at the pointer holding a lambda */
    std::shared_ptr<const lambda> ptr() const;

};

//! AST node for closures
/*! This node makes closures explicit. It encloses a sequence of
  identifiers, and an expression where these identifiers are used.
*/
class closure
    : public expression
{
protected:
    const std::shared_ptr<const tuple> m_args;
    const std::shared_ptr<const expression> m_body;

public:
/*!
  \param args Identifiers being closed over.
  \param body Expression where identifiers are used
  \param type Copperhead type.
  \param ctype C++ implementation type.
*/
    closure(const std::shared_ptr<const tuple> &args,
            const std::shared_ptr<const expression> &body,
            const std::shared_ptr<const type_t>& type = void_mt,
            const std::shared_ptr<const ctype::type_t>& ctype = ctype::void_mt);
    const tuple &args(void) const;
    const expression &body(void) const;
    /*! When we need to get at the pointer holding a closure */
    std::shared_ptr<const closure> ptr() const;

};

//! AST node for subscripting
class subscript
    : public expression
{
protected:
    const std::shared_ptr<const name> m_src;
    const std::shared_ptr<const expression> m_idx;

public:
/*!
  \param src Identifier being subscripted
  \param idx Subscript index
  \param type Copperhead type.
  \param ctype C++ implementation type.
*/
    subscript(const std::shared_ptr<const name> &src,
              const std::shared_ptr<const expression> &idx,
              const std::shared_ptr<const type_t>& type = void_mt,
              const std::shared_ptr<const ctype::type_t>& ctype = ctype::void_mt);
    const name &src(void) const;
    const expression &idx(void) const;
    /*! When we need to get at the pointer holding a subscript */
    std::shared_ptr<const subscript> ptr() const;

};

/*!
  @}
 */

}

max_stars_repo_name: bryancatanzaro/copperhead-compiler

max_issues_repo_name: bryancatanzaro/copperhead-compiler

max_forks_repo_name: bryancatanzaro/copperhead-compiler


text:
// Copyright Jim Bosch 2011-2012.
// 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)

/**
 *  A simple example showing how to wrap a couple of C++ functions that
 *  operate on 2-d arrays into Python functions that take NumPy arrays
 *  as arguments.
 *
 *  If you find have a lot of such functions to wrap, you may want to
 *  create a C++ array type (or use one of the many existing C++ array
 *  libraries) that maps well to NumPy arrays and create Boost.Python
 *  converters.  There's more work up front than the approach here,
 *  but much less boilerplate per function.  See the "Gaussian" example
 *  included with Boost.NumPy for an example of custom converters, or
 *  take a look at the "ndarray" project on GitHub for a more complete,
 *  high-level solution.
 *
 *  Note that we're using embedded Python here only to make a convenient
 *  self-contained example; you could just as easily put the wrappers
 *  in a regular C++-compiled module and imported them in regular
 *  Python.  Again, see the Gaussian demo for an example.
 */

#include <boost/python/numpy.hpp>
#include <boost/scoped_array.hpp>
#include <iostream>

namespace p = boost::python;
namespace np = boost::python::numpy;

// This is roughly the most efficient way to write a C/C++ function that operates
// on a 2-d NumPy array - operate directly on the array by incrementing a pointer
// with the strides.
void fill1(double * array, int rows, int cols, int row_stride, int col_stride) {
    double * row_iter = array;
    double n = 0.0; // just a counter we'll fill the array with.
    for (int i = 0; i < rows; ++i, row_iter += row_stride) {
        double * col_iter = row_iter;
        for (int j = 0; j < cols; ++j, col_iter += col_stride) {
            *col_iter = ++n;
        }
    }
}

// Here's a simple wrapper function for fill1.  It requires that the passed
// NumPy array be exactly what we're looking for - no conversion from nested
// sequences or arrays with other data types, because we want to modify it
// in-place.
void wrap_fill1(np::ndarray const & array) {
    if (array.get_dtype() != np::dtype::get_builtin<double>()) {
        PyErr_SetString(PyExc_TypeError, "Incorrect array data type");
        p::throw_error_already_set();
    }
    if (array.get_nd() != 2) {
        PyErr_SetString(PyExc_TypeError, "Incorrect number of dimensions");
        p::throw_error_already_set();
    }
    fill1(reinterpret_cast<double*>(array.get_data()),
          array.shape(0), array.shape(1),
          array.strides(0) / sizeof(double), array.strides(1) / sizeof(double));
}

// Another fill function that takes a double**.  This is less efficient, because
// it's not the native NumPy data layout, but it's common enough in C/C++ that
// it's worth its own example.  This time we don't pass the strides, and instead
// in wrap_fill2 we'll require the C_CONTIGUOUS bitflag, which guarantees that
// the column stride is 1 and the row stride is the number of columns.  That
// restricts the arrays that can be passed to fill2 (it won't work on most
// subarray views or transposes, for instance).
void fill2(double ** array, int rows, int cols) {
    double n = 0.0; // just a counter we'll fill the array with.
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            array[i][j] = ++n;
        }
    }
}
// Here's the wrapper for fill2; it's a little more complicated because we need
// to check the flags and create the array of pointers.
void wrap_fill2(np::ndarray const & array) {
    if (array.get_dtype() != np::dtype::get_builtin<double>()) {
        PyErr_SetString(PyExc_TypeError, "Incorrect array data type");
        p::throw_error_already_set();
    }
    if (array.get_nd() != 2) {
        PyErr_SetString(PyExc_TypeError, "Incorrect number of dimensions");
        p::throw_error_already_set();
    }
    if (!(array.get_flags() & np::ndarray::C_CONTIGUOUS)) {
        PyErr_SetString(PyExc_TypeError, "Array must be row-major contiguous");
        p::throw_error_already_set();
    }
    double * iter = reinterpret_cast<double*>(array.get_data());
    int rows = array.shape(0);
    int cols = array.shape(1);
    boost::scoped_array<double*> ptrs(new double*[rows]);
    for (int i = 0; i < rows; ++i, iter += cols) {
        ptrs[i] = iter;
    }
    fill2(ptrs.get(), array.shape(0), array.shape(1));
}

BOOST_PYTHON_MODULE(example) {
    np::initialize();  // have to put this in any module that uses Boost.NumPy
    p::def("fill1", wrap_fill1);
    p::def("fill2", wrap_fill2);
}

int main(int argc, char **argv)
{
    // This line makes our module available to the embedded Python intepreter.
# if PY_VERSION_HEX >= 0x03000000
    PyImport_AppendInittab("example", &PyInit_example);
# else
    PyImport_AppendInittab("example", &initexample);
# endif
    // Initialize the Python runtime.
    Py_Initialize();

    PyRun_SimpleString(
        "import example\n"
        "import numpy\n"
        "z1 = numpy.zeros((5,6), dtype=float)\n"
        "z2 = numpy.zeros((4,3), dtype=float)\n"
        "example.fill1(z1)\n"
        "example.fill2(z2)\n"
        "print z1\n"
        "print z2\n"
    );
    Py_Finalize();
}