text:
#include <blobfuse.h>
#include <boost/filesystem.hpp>
#include <string>
#include <signal.h>
#include <mntent.h>
#include <sys/types.h>
#include <dirent.h>
#include <pwd.h>

#include <include/StorageBfsClientBase.h>
#include <include/BlockBlobBfsClient.h>
#include <include/DataLakeBfsClient.h>

const std::string log_ident = "blobfuse";
struct cmdlineOptions cmd_options;
struct configParams config_options;
struct globalTimes_st globalTimes;
std::shared_ptr<StorageBfsClientBase> storage_client;

namespace {
    std::string trim(const std::string& str) {
        const size_t start = str.find_first_not_of(' ');
        if (std::string::npos == start) {
            return std::string();
        }
        const size_t end = str.find_last_not_of(' ');
        return str.substr(start, end - start + 1);
    }
}

#define OPTION(t, p) { t, offsetof(struct cmdlineOptions, p), 1 }
const struct fuse_opt option_spec[] =
{
    OPTION("--tmp-path=%s", tmp_path),
    OPTION("--config-file=%s", config_file),
    OPTION("--use-https=%s", useHttps),
    OPTION("--file-cache-timeout-in-seconds=%s", file_cache_timeout_in_seconds),
    OPTION("--container-name=%s", container_name),
    OPTION("--log-level=%s", log_level),
    OPTION("--use-attr-cache=%s", useAttrCache),
    OPTION("--use-adls=%s", use_adls),
    OPTION("--max-concurrency=%s", concurrency),
    OPTION("--cache-size-mb=%s", cache_size_mb),
    OPTION("--empty-dir-check=%s", empty_dir_check),
    OPTION("--version", version),
    OPTION("-v", version),
    OPTION("--help", help),
    OPTION("-h", help),
    FUSE_OPT_END
};

// Read Storage connection information from the environment variables
int read_config_env()
{
    char* env_account = getenv("AZURE_STORAGE_ACCOUNT");
    char* env_account_key = getenv("AZURE_STORAGE_ACCESS_KEY");
    char* env_sas_token = getenv("AZURE_STORAGE_SAS_TOKEN");
    char* env_blob_endpoint = getenv("AZURE_STORAGE_BLOB_ENDPOINT");
    char* env_identity_client_id = getenv("AZURE_STORAGE_IDENTITY_CLIENT_ID");
    char* env_identity_object_id = getenv("AZURE_STORAGE_IDENTITY_OBJECT_ID");
    char* env_identity_resource_id = getenv("AZURE_STORAGE_IDENTITY_RESOURCE_ID");
    char* env_managed_identity_endpoint = getenv("MSI_ENDPOINT");
    char* env_managed_identity_secret = getenv("MSI_SECRET");
    char* env_spn_client_id = getenv("AZURE_STORAGE_SPN_CLIENT_ID");
    char* env_spn_tenant_id = getenv("AZURE_STORAGE_SPN_TENANT_ID");
    char* env_spn_client_secret = getenv("AZURE_STORAGE_SPN_CLIENT_SECRET");
    char* env_auth_type = getenv("AZURE_STORAGE_AUTH_TYPE");
    char* env_aad_endpoint = getenv("AZURE_STORAGE_AAD_ENDPOINT");

    if(env_account)
    {
        config_options.accountName = env_account;

        if(env_account_key)
        {
            config_options.accountKey = env_account_key;
        }

        if(env_sas_token)
        {
            config_options.sasToken = env_sas_token;
        }

        if(env_identity_client_id)
        {
            config_options.identityClientId = env_identity_client_id;
        }

        if (env_spn_client_secret)
        {
            config_options.spnClientSecret = env_spn_client_secret;
        }

        if (env_spn_tenant_id)
        {
            config_options.spnTenantId = env_spn_tenant_id;
        }

        if (env_spn_client_id)
        {
            config_options.spnClientId = env_spn_client_id;
        }

        if(env_identity_object_id)
        {
            config_options.objectId = env_identity_object_id;
        }

        if(env_identity_resource_id)
        {
            config_options.resourceId = env_identity_resource_id;
        }

        if(env_managed_identity_endpoint)
        {
            config_options.msiEndpoint = env_managed_identity_endpoint;
        }

        if(env_managed_identity_secret)
        {
            config_options.msiSecret = env_managed_identity_secret;
        }

        if(env_auth_type)
        {
            config_options.authType = get_auth_type(env_auth_type);;
        } else {
            config_options.authType = get_auth_type();
        }

        if(env_aad_endpoint)
        {
            config_options.aadEndpoint = env_auth_type;
        }

        if(env_blob_endpoint) {
            // Optional to specify blob endpoint
            config_options.blobEndpoint = env_blob_endpoint;
        }
    }
    else
    {
        syslog(LOG_CRIT, "Unable to start blobfuse.  No config file was specified and the AZURE_STORAGE_ACCOUNT"
                         "environment variable was empty");
        fprintf(stderr, "Unable to start blobfuse.  No config file was specified and the AZURE_STORAGE_ACCOUNT"
                        "environment variable was empty\n");
        return -1;
    }

    return 0;
}

// Read Storage connection information from the config file
int read_config(const std::string configFile)
{
    std::ifstream file(configFile);
    if(!file)
    {
        syslog(LOG_CRIT, "Unable to start blobfuse.  No config file found at %s.", configFile.c_str());
        fprintf(stderr, "No config file found at %s.\n", configFile.c_str());
        return -1;
    }

    std::string line;
    std::istringstream data;
    bool set_auth_type = false;

    char* env_spn_client_secret = getenv("AZURE_STORAGE_SPN_CLIENT_SECRET");
    char* env_msi_secret = getenv("MSI_SECRET");

    if (env_spn_client_secret) {
        config_options.spnClientSecret = env_spn_client_secret;
    }

    if (env_msi_secret) {
        config_options.msiSecret = env_msi_secret;
    }

    while(std::getline(file, line))
    {
        // skip over comments
        if(line[0] == '#') {
            continue;
        }

<<<<<<< HEAD
        if(line.substr(0,1)=="#") {
            continue;
        }

        const std::string key(line.substr(0, line.find(" ")));
=======
        replace(line.begin(), line.end(), '\t', ' ');
>>>>>>> 8c4db0fdc03a29fc9c5e18711fa05fa0d4cdb04d
        data.str(line.substr(line.find(" ")+1));

        const std::string value(trim(data.str()));
<<<<<<< HEAD
        syslog(LOG_DEBUG, "Configuration file key: '%s'",key.c_str());
        syslog(LOG_DEBUG, "Configuration file value: '%s'",value.c_str());

        if(key=="accountName")
=======

        if(line.find("accountName") != std::string::npos)
>>>>>>> 8c4db0fdc03a29fc9c5e18711fa05fa0d4cdb04d
        {
            syslog(LOG_DEBUG, "Account name found");
            std::string accountNameStr(value);
            config_options.accountName = accountNameStr;
        }
        else if(key=="accountKey")
        {
            syslog(LOG_DEBUG, "Account Key found");
            std::string accountKeyStr(value);
            config_options.accountKey = accountKeyStr;
        }
        else if(key=="sasToken")
        {
<<<<<<< HEAD
            std::string sasTokenStr(value);
            str_options.sasToken = sasTokenStr;
=======
            syslog(LOG_DEBUG, "Sas Token found");
            std::string sasTokenStr(value);
            config_options.sasToken = sasTokenStr;
>>>>>>> 8c4db0fdc03a29fc9c5e18711fa05fa0d4cdb04d
        }
        else if(key=="containerName")
        {
            syslog(LOG_DEBUG, "Container name found");
            std::string containerNameStr(value);
            config_options.containerName = containerNameStr;
        }
        else if(key=="blobEndpoint")
        {
            std::string blobEndpointStr(value);
            config_options.blobEndpoint = blobEndpointStr;
        }
        else if(line.find("identityClientId") != std::string::npos)
        {
            std::string clientIdStr(value);
            config_options.identityClientId = clientIdStr;
        }
        else if(line.find("identityObjectId") != std::string::npos)
        {
            std::string objectIdStr(value);
            config_options.objectId = objectIdStr;
        }
        else if(line.find("identityResourceId") != std::string::npos)
        {
            std::string resourceIdStr(value);
            config_options.resourceId = resourceIdStr;
        }
<<<<<<< HEAD
        else if(key=="encryptionKey")
        {
            std::string encryptionKeyStr(value);
            str_options.encryptionKey = encryptionKeyStr;
        }
        else if(key=="encryptionKeySha256")
        {
            std::string encryptionKeySha256Str(value);
            str_options.encryptionKeySha256 = encryptionKeySha256Str;
        }
        else if(key=="encryptionAlgorithm")
        {
            std::string encryptionAlgorithmStr(value);
            str_options.encryptionAlgorithm = encryptionAlgorithmStr;
        }
=======
        else if(line.find("authType") != std::string::npos)
        {
            config_options.authType = get_auth_type(value);
            set_auth_type = true;
        }
        else if(line.find("msiEndpoint") != std::string::npos)
        {
            std::string msiEndpointStr(value);
            config_options.msiEndpoint = msiEndpointStr;
        }
        else if(line.find("servicePrincipalClientId") != std::string::npos)
        {
            std::string spClientIdStr(value);
            config_options.spnClientId = spClientIdStr;
        }
        else if(line.find("servicePrincipalTenantId") != std::string::npos)
        {
            std::string spTenantIdStr(value);
            config_options.spnTenantId = spTenantIdStr;
        }
        else if(line.find("servicePrincipalClientSecret") != std::string::npos)
        {
            std::string spClientSecretStr(value);
            config_options.spnClientSecret = spClientSecretStr;
        }
        else if(line.find("aadEndpoint") != std::string::npos)
        {
            std::cout << line.find("aadEndpoint");
            std::string altAADEndpointStr(value);
            config_options.aadEndpoint = altAADEndpointStr;
        }
        else if(line.find("logLevel") != std::string::npos)
        {
            std::string logLevel(value);
            config_options.logLevel = logLevel;
        }
        else if(line.find("accountType") != std::string::npos)
        {
            std::string acctType(value);
            if (acctType == "adls")
                config_options.useADLS = true;
        }
>>>>>>> 8c4db0fdc03a29fc9c5e18711fa05fa0d4cdb04d

        data.clear();
    }

    if(!set_auth_type)
    {
        config_options.authType = get_auth_type();
    }

    if(config_options.accountName.empty())
    {
        syslog (LOG_CRIT, "Unable to start blobfuse. Account name is missing in the config file.");
        fprintf(stderr, "Unable to start blobfuse. Account name is missing in the config file.\n");
        return -1;
    }
    else if(config_options.containerName.empty())
    {
        syslog (LOG_CRIT, "Unable to start blobfuse. Container name is missing in the config file.");
        fprintf(stderr, "Unable to start blobfuse. Container name is missing in the config file.\n");
        return -1;
    }
    else
    {
        return 0;
    }
}

void *azs_init(struct fuse_conn_info * conn)
{
<<<<<<< HEAD

    syslog(LOG_WARNING, "azs_init encryptionKeySha256: '%s'", str_options.encryptionKeySha256.c_str());
    if (str_options.use_attr_cache)
    {
        azure_blob_client_wrapper = std::make_shared<blob_client_attr_cache_wrapper>(blob_client_attr_cache_wrapper::blob_client_attr_cache_wrapper_init(str_options.accountName, str_options.accountKey, str_options.sasToken, 20/*concurrency*/, str_options.use_https,
                                                                                str_options.blobEndpoint, str_options.encryptionKey, str_options.encryptionKeySha256, str_options.encryptionAlgorithm));
    }
    else
    {
        azure_blob_client_wrapper = std::make_shared<blob_client_wrapper>(blob_client_wrapper::blob_client_wrapper_init(str_options.accountName, str_options.accountKey, str_options.sasToken, 20/*concurrency*/, str_options.use_https,
                                                                                str_options.blobEndpoint, str_options.encryptionKey, str_options.encryptionKeySha256, str_options.encryptionAlgorithm));
    }
=======
    syslog(LOG_DEBUG, "azs_init ran");
>>>>>>> 8c4db0fdc03a29fc9c5e18711fa05fa0d4cdb04d

    /*
    cfg->attr_timeout = 360;
    cfg->kernel_cache = 1;
    cfg->entry_timeout = 120;
    cfg->negative_timeout = 120;
    */
    if (kernel_version < 5.4) {
        conn->max_write = 4194304;
        //conn->max_read = 4194304;
    } else {
        conn->want |= FUSE_CAP_BIG_WRITES;
    }
    conn->max_readahead = 4194304;
    conn->max_background = 128;
    //  conn->want |= FUSE_CAP_WRITEBACK_CACHE | FUSE_CAP_EXPORT_SUPPORT; // TODO: Investigate putting this back in when we downgrade to fuse 2.9

    g_gc_cache = std::make_shared<gc_cache>(config_options.tmpPath, config_options.fileCacheTimeoutInSeconds);
    g_gc_cache->run();

    if (config_options.authType == MSI_AUTH ||
        config_options.authType == SPN_AUTH)
    {
        std::shared_ptr<OAuthTokenCredentialManager> tokenManager = GetTokenManagerInstance(EmptyCallback);
        tokenManager->StartTokenMonitor();
    }

    return NULL;
}

// TODO: print FUSE usage as well
void print_usage()
{
    fprintf(stdout, "Usage: blobfuse <mount-folder> --tmp-path=</path/to/fusecache> [--config-file=</path/to/config.cfg> | --container-name=<containername>]");
    fprintf(stdout, "    [--use-https=true] [--file-cache-timeout-in-seconds=120] [--log-level=LOG_OFF|LOG_CRIT|LOG_ERR|LOG_WARNING|LOG_INFO|LOG_DEBUG] [--use-attr-cache=true]\n\n");
    fprintf(stdout, "In addition to setting --tmp-path parameter, you must also do one of the following:\n");
    fprintf(stdout, "1. Specify a config file (using --config-file]=) with account name (accountName), container name (containerName), and\n");
    fprintf(stdout,  "\ta. account key (accountKey),\n");
    fprintf(stdout,  "\tb. account SAS token (sasToken),\n");
    fprintf(stdout,  "\tc. valid service principal credentials (servicePrincipalClientId, servicePrincipalTenantId, and environment variable AZURE_STORAGE_SPN_CLIENT_SECRET) with access to the storage account or,\n");
    fprintf(stdout,  "\td. valid MSI credentials (one or none of identityClientId, identityObjectId, identityResourceId) with access to the storage account. Custom endpoints w/ secrets can be used via msiEndpoint and MSI_SECRET\n");
    fprintf(stdout, "2. Set the environment variables AZURE_STORAGE_ACCOUNT and (AZURE_STORAGE_ACCESS_KEY or AZURE_STORAGE_SAS_TOKEN), and specify the container name with --container-name=\n\n");
    fprintf(stdout, "See https://github.com/Azure/azure-storage-fuse for detailed installation and advanced configuration instructions, including SPN and MSI via environment variables.\n");
}

void print_version()
{
    fprintf(stdout, "blobfuse %s\n", BFUSE_VER);
}

int set_log_mask(const char * min_log_level_char, bool blobfuseInit)
{
    if (!min_log_level_char)
    {
        syslog(LOG_CRIT, "Setting logging level to : LOG_WARNING");
        setlogmask(LOG_UPTO(LOG_WARNING));
        return 0;
    }
    gEnableLogsHttp = false;

    std::string min_log_level(min_log_level_char);
    if (min_log_level.empty())
    {
        syslog(LOG_CRIT, "Setting logging level to : LOG_WARNING");
        setlogmask(LOG_UPTO(LOG_WARNING));
        return 0;
    }

    syslog(LOG_CRIT, "Setting logging level to : %s", min_log_level.c_str());

    // cmd_options for logging: LOG_OFF, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_INFO, LOG_DEBUG
    if (min_log_level == "LOG_OFF")
    {
        setlogmask(LOG_UPTO(LOG_EMERG)); // We don't use 'LOG_EMERG', so this won't log anything.
        return 0;
    }
    if (min_log_level == "LOG_CRIT")
    {
        setlogmask(LOG_UPTO(LOG_CRIT));
        return 0;
    }
    if (min_log_level == "LOG_ERR")
    {
        setlogmask(LOG_UPTO(LOG_ERR));
        return 0;
    }
    if (min_log_level == "LOG_WARNING")
    {
        setlogmask(LOG_UPTO(LOG_WARNING));
        return 0;
    }
    if (min_log_level == "LOG_INFO")
    {
        gEnableLogsHttp = true;
        setlogmask(LOG_UPTO(LOG_INFO));
        return 0;
    }
    if (min_log_level == "LOG_DEBUG")
    {
        gEnableLogsHttp = true;
        setlogmask(LOG_UPTO(LOG_DEBUG));
        return 0;
    }

    if (blobfuseInit) {
        syslog(LOG_CRIT, "Unable to start blobfuse. Error: Invalid log level \"%s\"", min_log_level.c_str());
        fprintf(stderr, "Error: Invalid log level \"%s\".  Permitted values are LOG_OFF, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_INFO, LOG_DEBUG.\n", min_log_level.c_str());
        fprintf(stdout, "If not specified, logging will default to LOG_WARNING.\n\n");
    } else {
        set_log_mask(cmd_options.log_level, false);
    }
    return 1;
}

/*
 *  This function is called only during SIGUSR1 handling.
 *  Objective here is to read only the 'logLevel' from the config file
 *  If logLevel is removed from config file then reset the logging level
 *  back to what was provided int the command line cmd_options, otherwise use
 *  this config as the new logging level..
 */
int refresh_from_config_file(const std::string configFile)
{
    std::ifstream file(configFile);
    if(!file)
    {
        syslog(LOG_CRIT, "Unable to read config file : %s", configFile.c_str());
        return -1;
    }

    std::string line;
    bool logLevelFound = false;
    while(std::getline(file, line))
    {
        // skip over comments
        if(line[0] == '#') {
            continue;
        }

       std::size_t pos = line.find("logLevel");
        if(pos != std::string::npos)
        {
           std::string logLevel = line.substr(line.find(" ")+1);
           config_options.logLevel = trim(logLevel);
            logLevelFound = true;
        }
    }

    if(!logLevelFound) {
        config_options.logLevel = (cmd_options.log_level) ? : "";
    }

    return 0;
}

void sig_usr_handler(int signum)
{
    if (signum == SIGUSR1) {
        syslog(LOG_INFO, "Received signal SIGUSR1");
        if (0 == refresh_from_config_file(cmd_options.config_file)) {
            set_log_mask(config_options.logLevel.c_str(), false);
        }
    }
}

void set_up_callbacks(struct fuse_operations &azs_blob_operations)
{
    openlog(log_ident.c_str(), LOG_NDELAY | LOG_PID, 0);

    // Here, we set up all the callbacks that FUSE requires.
    azs_blob_operations.init = azs_init;
    azs_blob_operations.getattr = azs_getattr;
    azs_blob_operations.statfs = azs_statfs;
    azs_blob_operations.access = azs_access;
    azs_blob_operations.readlink = azs_readlink;
    azs_blob_operations.symlink = azs_symlink;
    azs_blob_operations.readdir = azs_readdir;
    azs_blob_operations.open = azs_open;
    azs_blob_operations.read = azs_read;
    azs_blob_operations.release = azs_release;
    azs_blob_operations.fsync = azs_fsync;
    azs_blob_operations.create = azs_create;
    azs_blob_operations.write = azs_write;
    azs_blob_operations.mkdir = azs_mkdir;
    azs_blob_operations.unlink = azs_unlink;
    azs_blob_operations.rmdir = azs_rmdir;
    azs_blob_operations.chown = azs_chown;
    azs_blob_operations.chmod = azs_chmod;
    //#ifdef HAVE_UTIMENSAT
    azs_blob_operations.utimens = azs_utimens;
    //#endif
    azs_blob_operations.destroy = azs_destroy;
    azs_blob_operations.truncate = azs_truncate;
    azs_blob_operations.rename = azs_rename;
    azs_blob_operations.setxattr = azs_setxattr;
    azs_blob_operations.getxattr = azs_getxattr;
    azs_blob_operations.listxattr = azs_listxattr;
    azs_blob_operations.removexattr = azs_removexattr;
    azs_blob_operations.flush = azs_flush;

    signal(SIGUSR1, sig_usr_handler);
}

/*
 *  Check if the given directory is already mounted for the mounttype fuse or not
 *  If mounted then re-mounting again shall fail.
 */
bool is_directory_mounted(const char* mntDir) {
     struct mntent *mnt_ent;
     bool found = false;
     FILE *mnt_list;

     mnt_list = setmntent(_PATH_MOUNTED, "r");
     while ((mnt_ent = getmntent(mnt_list)))
     {
         if (!strcmp(mnt_ent->mnt_dir, mntDir) && !strcmp(mnt_ent->mnt_type, "fuse"))
         {
             found = true;
             break;
         }
     }
     endmntent(mnt_list);
     return found;

}

/*
 *  Check if the given temp directory is empty or not
 *  If non-empty then return false, as this can create issues in
 *  out cache.
 */
bool is_directory_empty(const char *tmpDir) {
    int cnt = 0;
    struct dirent *d_ent;

    DIR *dir = opendir(tmpDir);
    if (dir == NULL)
        return 0;

    // Count number of entries in directory
    // if its more then 2 (. and ..) then its not empty
    while (((d_ent = readdir(dir)) != NULL)
            && (cnt++ <= 2));
    closedir(dir);

    //fprintf(stdout, "count of dir entries %u", cnt);
    return (cnt <= 2);
}

int read_and_set_arguments(int argc, char *argv[], struct fuse_args *args)
{
    // FUSE has a standard method of argument parsing, here we just follow the pattern.
    *args = FUSE_ARGS_INIT(argc, argv);

    // Check for existence of allow_other flag and change the default permissions based on that
    config_options.defaultPermission = 0770;
    std::vector<std::string> string_args(argv, argv+argc);
    for (size_t i = 1; i < string_args.size(); ++i) {
      if (string_args[i].find("allow_other") != std::string::npos) {
          config_options.defaultPermission = 0777;
      }
    }

    int ret = 0;
    config_options.useADLS = false;
    try
    {

        if (fuse_opt_parse(args, &cmd_options, option_spec, NULL) == -1)
        {
            return 1;
        }

        if(cmd_options.version)
        {
            print_version();
            exit(0);
        }

        if(cmd_options.help)
        {
            print_usage();
            exit(0);
        }

        if (args && args->argv && argc > 1 &&
            is_directory_mounted(argv[1]))
        {
            syslog(LOG_CRIT, "Unable to start blobfuse. '%s'is already mounted.", argv[1]);
            fprintf(stderr, "Error: '%s' is already mounted. Recheck your config\n", argv[1]);
            return 1;
        }

        if(!cmd_options.config_file)
        {
            if(!cmd_options.container_name)
            {
                syslog(LOG_CRIT, "Unable to start blobfuse, no config file provided and --container-name is not set.");
                fprintf(stderr, "Error: No config file provided and --container-name is not set.\n");
                print_usage();
                return 1;
            }

            std::string container(cmd_options.container_name);
            config_options.containerName = container;
            ret = read_config_env();
        }
        else
        {
            ret = read_config(cmd_options.config_file);
        }

        if (ret != 0)
        {
            return ret;
        }
    }
    catch(std::exception &)
    {
        print_usage();
        return 1;
    }

    int res = set_log_mask(cmd_options.log_level, true);
    if (res != 0)
    {
        print_usage();
        return 1;
    }

    // remove last trailing slash in tmp_path
    if(!cmd_options.tmp_path)
    {
        fprintf(stderr, "Error: --tmp-path is not set.\n");
        print_usage();
        return 1;
    }

    std::string tmpPathStr(cmd_options.tmp_path);
    if (!tmpPathStr.empty())
    {
        // First let's normalize the path
        // Don't use canonical because that will check for path existence and permissions
#if BOOST_VERSION > 106000 // lexically_normal was added in boost 1.60.0; ubuntu 16 is only up to 1.58.0
        tmpPathStr = boost::filesystem::path(tmpPathStr).lexically_normal().string();
#else
        tmpPathStr = boost::filesystem::path(tmpPathStr).normalize().string();
#endif

        // Double check that we have not just emptied this string
        if (!tmpPathStr.empty())
        {
            // Trim any trailing '/' or '/.'
            // This will also create a blank string for just '/' which will fail out at the next block
            // .lexically_normal() returns '/.' for directories
            if (tmpPathStr[tmpPathStr.size() - 1] == '/')
            {
                tmpPathStr.erase(tmpPathStr.size() - 1);
            }
            else if (tmpPathStr.size() > 1 && tmpPathStr.compare((tmpPathStr.size() - 2), 2, "/.") == 0)
            {
                tmpPathStr.erase(tmpPathStr.size() - 2);
            }

            if (tmpPathStr[0] == '~') {
                const char *homedir = NULL;
                if ((homedir = getenv("HOME")) == NULL) {
                    homedir = getpwuid(getuid())->pw_dir;
                }
                if (homedir) {
                    syslog(LOG_ERR,"Expanding '~' in tmppath to %s", homedir);
                    tmpPathStr = std::string(homedir) + tmpPathStr.substr(1);
                }
            }
        }

        // Error out if we emptied this string
        if (tmpPathStr.empty())
        {
            fprintf(stderr, "Error: --tmp-path resolved to empty path.\n");
            print_usage();
            return 1;
        }
    }

    config_options.emptyDirCheck = false;
    if (cmd_options.empty_dir_check != NULL) {
        std::string val(cmd_options.empty_dir_check);
        if(val == "true")
        {
            config_options.emptyDirCheck = true;
        }
    }

    if (!tmpPathStr.empty())
    {
        bool fail_mount = false;
        struct stat sb;

        // if the directory does not exist no need to valdiate if it is empty
        // so check if the dir exists first and then validate
        if (stat(tmpPathStr.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode))
        {
            if  (!is_directory_empty(tmpPathStr.c_str()) &&
                 config_options.emptyDirCheck)
            {
                // Tmp path exists. if 'root' directory is empty then also its fine
                std::string tmprootPath = tmpPathStr + "/root";
                if (stat(tmprootPath.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) {
                    if  (!is_directory_empty(tmprootPath.c_str())) {
                        fail_mount = true;
                    }
                } else {
                    fail_mount = true;
                }

                if (fail_mount) {
                    syslog(LOG_CRIT, "Unable to start blobfuse. temp directory '%s'is not empty.", tmpPathStr.c_str());
                    fprintf(stderr, "Error: temp directory '%s' is not empty. blobfuse needs an empty temp directory\n", tmpPathStr.c_str());
                    return 1;
                }
            }
        }
    }

    config_options.tmpPath = tmpPathStr;
    config_options.useHttps = true;
    if (cmd_options.useHttps != NULL)
    {
        std::string https(cmd_options.useHttps);
        if (https == "false")
        {
            config_options.useHttps = false;
        }
    }

    config_options.useAttrCache = false;
    if (cmd_options.useAttrCache != NULL)
    {
        std::string attr_cache(cmd_options.useAttrCache);
        if (attr_cache == "true")
        {
            config_options.useAttrCache = true;
        }
    }

    if (cmd_options.file_cache_timeout_in_seconds != NULL)
    {
        std::string timeout(cmd_options.file_cache_timeout_in_seconds);
        config_options.fileCacheTimeoutInSeconds = stoi(timeout);
    }
    else
    {
        config_options.fileCacheTimeoutInSeconds = 120;
    }

    if(cmd_options.use_adls != NULL)
    {
        std::string use_adls_value(cmd_options.use_adls);
        if(use_adls_value == "true")
        {
            config_options.useADLS = true;
        } else if(use_adls_value == "false") {
            config_options.useADLS = false;
        }
    }

    config_options.concurrency = (int)(blobfuse_constants::def_concurrency_blob_wrapper);
    if(cmd_options.concurrency != NULL)
    {
        std::string concur(cmd_options.concurrency);
        //config_options.concurrency = stoi(concur);
        config_options.concurrency = (stoi(concur) < blobfuse_constants::max_concurrency_blob_wrapper) ?
                stoi(concur) : blobfuse_constants::max_concurrency_blob_wrapper;
    }

    config_options.cacheSize = 0;
    if (cmd_options.cache_size_mb != NULL)
    {
        std::string cache_size(cmd_options.cache_size_mb);
        config_options.cacheSize = stoi(cache_size) * (unsigned long long)(1024l * 1024l);
    }

    return 0;
}

int configure_tls()
{
    // For proper locking, instructing gcrypt to use pthreads
    gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
    if(GNUTLS_E_SUCCESS != gnutls_global_init())
    {
        syslog (LOG_CRIT, "Unable to start blobfuse. GnuTLS initialization failed: errno = %d.\n", errno);
        fprintf(stderr, "GnuTLS initialization failed: errno = %d.\n", errno);
        return 1;
    }
    return 0;
}

void configure_fuse(struct fuse_args *args)
{
<<<<<<< HEAD
    // The current implementation of blob_client_wrapper calls curl_global_init() in the constructor, and curl_global_cleanup in the destructor.
    // Unfortunately, curl_global_init() has to be called in the same process as any HTTPS calls that are made, otherwise NSS is not configured properly.
    // When running in daemon mode, the current process forks() and exits, while the child process lives on as a daemon.
    // So, here we create and destroy a temp blob client in order to test the connection info, and we create the real one in azs_init, which is called after the fork().
    {
        const int defaultMaxConcurrency = 20;
        blob_client_wrapper temp_azure_blob_client_wrapper = blob_client_wrapper::blob_client_wrapper_init(str_options.accountName, str_options.accountKey, str_options.sasToken, defaultMaxConcurrency, str_options.use_https,
													   str_options.blobEndpoint, str_options.encryptionKey, str_options.encryptionKeySha256, str_options.encryptionAlgorithm);
        if(errno != 0)
        {
            syslog(LOG_CRIT, "Unable to start blobfuse.  Creating local blob client failed: errno = %d.\n", errno);
            fprintf(stderr, "Creating blob client failed: errno = %d.\n", errno);
            return 1;
        }
=======
    populate_kernel_version();
>>>>>>> 8c4db0fdc03a29fc9c5e18711fa05fa0d4cdb04d

    if (kernel_version < 5.4) {
        fuse_opt_add_arg(args, "-omax_read=131072");
        fuse_opt_add_arg(args, "-omax_write=131072");
    }

    if (cmd_options.file_cache_timeout_in_seconds != NULL)
    {
        std::string timeout(cmd_options.file_cache_timeout_in_seconds);
        config_options.fileCacheTimeoutInSeconds = stoi(timeout);
    }
    else
    {
        config_options.fileCacheTimeoutInSeconds = 120;
    }

    // FUSE contains a feature where it automatically implements 'soft' delete if one process has a file open when another calls unlink().
    // This feature causes us a bunch of problems, so we use "-ohard_remove" to disable it, and track the needed 'soft delete' functionality on our own.
    fuse_opt_add_arg(args, "-ohard_remove");
    fuse_opt_add_arg(args, "-obig_writes");
    fuse_opt_add_arg(args, "-ofsname=blobfuse");
    fuse_opt_add_arg(args, "-okernel_cache");
    umask(0);
}

int initialize_blobfuse()
{
    if(0 != ensure_files_directory_exists_in_cache(prepend_mnt_path_string("/placeholder")))
    {
        syslog(LOG_CRIT, "Unable to start blobfuse.  Failed to create directory on cache directory: %s, errno = %d.\n", prepend_mnt_path_string("/placeholder").c_str(),  errno);
        fprintf(stderr, "Failed to create directory on cache directory: %s, errno = %d.\n", prepend_mnt_path_string("/placeholder").c_str(),  errno);
        return 1;
    }
        //initialize storage client and authenticate, if we fail here, don't call fuse
    if (config_options.useADLS)
    {
        syslog(LOG_INFO, "Initializing blobfuse using DataLake");
        storage_client = std::make_shared<DataLakeBfsClient>(config_options);
    }
    else
    {
        syslog(LOG_DEBUG, "Initializing blobfuse using BlockBlob");
        storage_client = std::make_shared<BlockBlobBfsClient>(config_options);
        syslog(LOG_DEBUG, "Setup storage client");
    }
    if(storage_client->AuthenticateStorage())
    {
        syslog(LOG_DEBUG, "Successfully Authenticated!");
    }
    else
    {
        syslog(LOG_ERR, "Unable to start blobfuse due to a lack of credentials. Please check the readme for valid auth setups.");
        return -1;
    }

    globalTimes.lastModifiedTime = globalTimes.lastAccessTime = globalTimes.lastChangeTime = time(NULL);
    return 0;
}

max_stars_repo_name: hcordobest/azure-storage-fuse

max_issues_repo_name: hcordobest/azure-storage-fuse

max_forks_repo_name: hcordobest/azure-storage-fuse


text:
/*
 * Licensed to Green Energy Corp (www.greenenergycorp.com) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership.  Green Enery
 * Corp licenses this file to you 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.
 */

#include "VtoReader.h"

#include "DNPConstants.h"
#include "EnhancedVto.h"

#include <APL/Exception.h>
#include <APL/Logger.h>

#include <boost/foreach.hpp>

namespace apl
{
namespace dnp
{

void VtoReader::AddVtoChannel(IVtoDataHandler* apCallbacks)
{
	/*
	 * The whole function is thread-safe, from start to finish.
	 */
	CriticalSection cs(&mLock);

	boost::uint8_t id = apCallbacks->GetChannelId();

	/* Has this channel id already been registered? */
	if (mChannelMap.find(id) != mChannelMap.end()) {
		std::stringstream out;
		out << (int)id;

		throw ArgumentException(
		    LOCATION,
		    "Channel already registered: " +
		    out.str() );
	}

	/* Register the callbacks for the channel id */
	mChannelMap[id] = apCallbacks;
}

void VtoReader::RemoveVtoChannel(IVtoDataHandler* apCallbacks)
{
	/*
	 * The whole function is thread-safe, from start to finish.
	 */
	CriticalSection cs(&mLock);

	boost::uint8_t id = apCallbacks->GetChannelId();

	if (mChannelMap.erase(id) == 0) {
		std::stringstream out;
		out << (int)id;

		throw ArgumentException( LOCATION,
		                         "Channel not registered: " + out.str() );
	}
}

void VtoReader::UpdateEnhancedVto(const VtoData& arData, boost::uint8_t aChannelId)
{
	bool remoteOnline;
	boost::uint8_t realChannel;
	try {
		EnhancedVto::ReadVtoData(arData, remoteOnline, realChannel);
		ChannelMap::iterator i = mChannelMap.find(realChannel);

		if (i == mChannelMap.end()) {
			ERROR_BLOCK(LEV_ERROR,
			            "Received enhanced Vto control message for unregistered channel: " << realChannel,
			            VTOERR_ENHANCED_VTO_FOR_UNREGISTERED_CHANNEL);
		}
		else {
			VtoData data(remoteOnline ? VTODT_REMOTE_OPENED : VTODT_REMOTE_CLOSED);
			i->second->OnVtoDataReceived(data);
		}
	}
	catch(Exception ex) {
		ERROR_BLOCK(LEV_WARNING, ex.GetErrorString(), VTOERR_BADLY_FORMATTED_ENHANCED_VTO);
	}
}

void VtoReader::UpdateNormalVto(const VtoData& arData, boost::uint8_t aChannelId)
{
	ChannelMap::iterator i = mChannelMap.find(aChannelId);

	if (i == mChannelMap.end()) {
		ERROR_BLOCK(LEV_ERROR,
		            "No registered callback handler for received data "
		            "on VTO channel id: " + aChannelId,
		            VTOERR_VTO_FOR_UNEXPECTED_CHANNEL);
	}
	else {
		i->second->OnVtoDataReceived(arData);
	}
}

void VtoReader::Update(const VtoData& arData,
                       boost::uint8_t aChannelId)
{
	/* Make sure we are part of the larger DNP3 transaction */
	assert( this->InProgress() );

	if(aChannelId == 255) {
		this->UpdateEnhancedVto(arData, aChannelId);
	}
	else {
		this->UpdateNormalVto(arData, aChannelId);
	}
}

void VtoReader::_Start()
{
	mLock.Lock();
}

void VtoReader::_End()
{
	mLock.Unlock();
}
}
}

/* vim: set ts=4 sw=4: */

ext: cpp


text:
//
// Copyright (c) 2021 Richard Hodges (hodges.r@gmail.com)
//
// 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)
//
// Official repository: https://github.com/madmongo1/router
//

#include <boost/asio/io_context.hpp>
#include <boost/asio/strand.hpp>
#include <boost/asio/thread_pool.hpp>
#include <boost/connector/util/check_executor.hpp>

namespace boost::connector::util
{
bool
check_executor(asio::any_io_executor const &e)
{
    if (e.target_type() == typeid(asio::io_context::executor_type))
        return e.target< asio::io_context::executor_type >()->running_in_this_thread();
    if (e.target_type() == typeid(asio::strand< asio::io_context::executor_type >))
        return e.target< asio::strand< asio::io_context::executor_type > >()->running_in_this_thread();
    if (e.target_type() == typeid(asio::thread_pool::executor_type))
        return e.target< asio::thread_pool::executor_type >()->running_in_this_thread();
    if (e.target_type() == typeid(asio::strand< asio::thread_pool::executor_type >))
        return e.target< asio::strand< asio::thread_pool::executor_type > >()->running_in_this_thread();

    // return true for any executor types we don't know about.
    // This function is intended to be used in assert statements, so needn't be 100% accurate in all cases
    return true;
}

}   // namespace boost::connector::util


text: #include <boost/mpl/aux_/logical_op.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
#ifdef MEX

#include <mex.h>
#include <igl/C_STR.h>
#include <igl/matlab/mexErrMsgTxt.h>
#undef assert
#define assert( isOK ) ( (isOK) ? (void)0 : (void) mexErrMsgTxt(C_STR(__FILE__<<":"<<__LINE__<<": failed assertion `"<<#isOK<<"'"<<std::endl) ) )
#endif
#include <igl/matlab/MexStream.h>

#include <igl/per_vertex_normals.h>
#include <igl/parallel_for.h>
#include <igl/signed_distance.h>
#include <igl/per_edge_normals.h>
#include <igl/matlab/validate_arg.h>
#include <igl/per_face_normals.h>
#include <igl/WindingNumberAABB.h>
#include <igl/matlab/prepare_lhs.h>
#include <igl/matlab/parse_rhs.h>
#include <igl/C_STR.h>

#include <Eigen/Core>
#include <iostream>

void parse_rhs(
  const int nrhs,
  const mxArray *prhs[],
  Eigen::MatrixXd & P,
  Eigen::MatrixXd & V,
  Eigen::MatrixXi & F,
  igl::SignedDistanceType & type)
{
  using namespace std;
  using namespace igl;
  using namespace igl::matlab;
  using namespace Eigen;
  mexErrMsgTxt(nrhs >= 3, "The number of input arguments must be >=3.");

  const int dim = mxGetN(prhs[0]);

  parse_rhs_double(prhs,P);
  parse_rhs_double(prhs+1,V);
  parse_rhs_index(prhs+2,F);

  mexErrMsgTxt(P.cols()==3 || P.cols()==2,"P must be #P by (3|2)");
  mexErrMsgTxt(V.cols()==3 || V.cols()==2,"V must be #V by (3|2)");
  mexErrMsgTxt(V.cols()==P.cols(),"dim(V) must be dim(P)");
  mexErrMsgTxt(F.cols()==V.cols(),"F must be #F by dim(V)");

  type = SIGNED_DISTANCE_TYPE_PSEUDONORMAL;
  {
    int i = 3;
    while(i<nrhs)
    {
      mexErrMsgTxt(mxIsChar(prhs[i]),"Parameter names should be strings");
      // Cast to char
      const char * name = mxArrayToString(prhs[i]);
      if(strcmp("SignedDistanceType",name) == 0)
      {
        validate_arg_char(i,nrhs,prhs,name);
        const char * type_name = mxArrayToString(prhs[++i]);
        if(strcmp("pseudonormal",type_name)==0)
        {
          type = igl::SIGNED_DISTANCE_TYPE_PSEUDONORMAL;
        }else if(strcmp("winding_number",type_name)==0)
        {
          type = igl::SIGNED_DISTANCE_TYPE_WINDING_NUMBER;
        }else
        {
          mexErrMsgTxt(false,C_STR("Unknown SignedDistanceType: "<<type_name));
        }
      }else
      {
        mexErrMsgTxt(false,"Unknown parameter");
      }
      i++;
    }
  }
}

//void precompute(
//  const Eigen::MatrixXd & V,
//  const Eigen::MatrixXi & F,
//  const igl::SignedDistanceType sign_type,
//  State & state)
//{
//  using namespace igl;
//  using namespace std;
//  using namespace Eigen;

  // This will remember the data structures for subsequent calls (without an
  // calls in between with different (V,F) or type
  static Eigen::MatrixXd g_V;
  static Eigen::MatrixXi g_F;
  static igl::SignedDistanceType g_sign_type =
    igl::NUM_SIGNED_DISTANCE_TYPE;
  static igl::AABB<Eigen::MatrixXd,3> g_tree;
  static igl::WindingNumberAABB<
    Eigen::RowVector3d,
    Eigen::MatrixXd,
    Eigen::MatrixXi> g_hier;
  static Eigen::MatrixXd g_FN,g_VN,g_EN;
  static Eigen::MatrixXi g_E;
  static Eigen::VectorXi g_EMAP;

void mexFunction(
  int nlhs, mxArray *plhs[],
  int nrhs, const mxArray *prhs[])
{
  using namespace std;
  using namespace Eigen;
  using namespace igl;
  using namespace igl::matlab;

  igl::matlab::MexStream mout;
  std::streambuf *outbuf = cout.rdbuf(&mout);
  //mexPrintf("Compiled at %s on %s\n",__TIME__,__DATE__);

  MatrixXd P,V,C,N;
  MatrixXi F;
  VectorXi I;
  VectorXd S;
  SignedDistanceType type;
  parse_rhs(nrhs,prhs,P,V,F,type);

  if(F.rows() > 0)
  {
    switch(V.cols())
    {
      case 2:
      {
        // Persistent data not supported for 2D
        signed_distance(P,V,F,type,S,I,C,N);
        break;
      }
      case 3:
      {
        if(g_sign_type != type || g_V != V || g_F != F)
        {
          g_V = V;
          g_F = F;
          g_sign_type = type;
          // Clear the tree
          g_tree.deinit();

          // Prepare distance computation
          g_tree.init(V,F);
          switch(type)
          {
            default:
              assert(false && "Unknown SignedDistanceType");
            case SIGNED_DISTANCE_TYPE_DEFAULT:
            case SIGNED_DISTANCE_TYPE_WINDING_NUMBER:
              g_hier.set_mesh(V,F);
              g_hier.grow();
              break;
            case SIGNED_DISTANCE_TYPE_PSEUDONORMAL:
              // "Signed Distance Computation Using the Angle Weighted Pseudonormal"
              // [Bærentzen & Aanæs 2005]
              per_face_normals(V,F,g_FN);
              per_vertex_normals(V,F,PER_VERTEX_NORMALS_WEIGHTING_TYPE_ANGLE,
                g_FN,g_VN);
              per_edge_normals(
                V,F,PER_EDGE_NORMALS_WEIGHTING_TYPE_UNIFORM,
                g_FN,g_EN,g_E,g_EMAP);
              break;
          }
        }

        N.resize(P.rows(),3);
        S.resize(P.rows(),1);
        I.resize(P.rows(),1);
        C.resize(P.rows(),3);
        //for(int p = 0;p<P.rows();p++)
        igl::parallel_for(P.rows(),[&](const int p)
        {
          const Eigen::RowVector3d q(P(p,0),P(p,1),P(p,2));
          double s,sqrd;
          Eigen::RowVector3d c;
          int i;
          switch(type)
          {
            default:
              assert(false && "Unknown SignedDistanceType");
            case SIGNED_DISTANCE_TYPE_DEFAULT:
            case SIGNED_DISTANCE_TYPE_WINDING_NUMBER:
              signed_distance_winding_number(
                g_tree,g_V,g_F,g_hier,q,s,sqrd,i,c);
              break;
            case SIGNED_DISTANCE_TYPE_PSEUDONORMAL:
            {
              RowVector3d n(0,0,0);
              signed_distance_pseudonormal(
                g_tree,g_V,g_F,g_FN,g_VN,g_EN,g_EMAP,
                q,s,sqrd,i,c,n);
              N.row(p) = n;
              break;
            }
          }
          I(p) = i;
          S(p) = s*sqrt(sqrd);
          C.row(p) = c;
        },10000);
        break;
      }
    }
  }

  switch(nlhs)
  {
    default:
    {
      mexErrMsgTxt(false,"Too many output parameters.");
    }
    case 4:
    {
      prepare_lhs_double(N,plhs+3);
      // Fall through
    }
    case 3:
    {
      prepare_lhs_double(C,plhs+2);
      // Fall through
    }
    case 2:
    {
      prepare_lhs_index(I,plhs+1);
      // Fall through
    }
    case 1:
    {
      prepare_lhs_double(S,plhs+0);
      // Fall through
    }
    case 0: break;
  }

  // Restore the std stream buffer Important!
  std::cout.rdbuf(outbuf);
}


text:
/******************************************************************************
 * Copyright (c) 2016 Sergey Alexandrov
 *
 * 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.
 ******************************************************************************/

#include <chrono>

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

#include <librealsense/rs.hpp>

#include <grabbers/realsense_grabber.h>

namespace grabbers {

struct RealSenseGrabber::Impl {
  rs::context ctx;
  rs::device* device;

  cv::Size color_image_resolution = {0, 0};
  int next_frame_index = 0;

  uint64_t timestamp_zero_offset = 0;

  Impl() {
    if (ctx.get_device_count() == 0)
      BOOST_THROW_EXCEPTION(GrabberException("No RealSense devices connected"));

    device = ctx.get_device(0);
    // device->enable_stream(rs::stream::color, rs::preset::best_quality);
    device->enable_stream(rs::stream::color, 640, 480, rs::format::bgr8, 15);

    if (!device->is_stream_enabled(rs::stream::color) ||
        device->get_stream_format(rs::stream::color) != rs::format::bgr8)
      BOOST_THROW_EXCEPTION(GrabberException("Failed to create color stream with requested format"));

    color_image_resolution.width = device->get_stream_width(rs::stream::color);
    color_image_resolution.height = device->get_stream_height(rs::stream::color);

    device->start();
  }

  ~Impl() {
    if (device->is_streaming())
      device->stop();
    device->disable_stream(rs::stream::color);
  }

  double grabFrame(cv::Mat& color) {
    device->wait_for_frames();

    auto color_data = device->get_frame_data(rs::stream::color);
    memcpy(color.data, color_data, color.total() * color.elemSize());

    ++next_frame_index;
    return computeTimestamp(device->get_frame_timestamp(rs::stream::color));
  }

  double computeTimestamp(int device_timestamp) {
    if (timestamp_zero_offset == 0) {
      auto now = std::chrono::high_resolution_clock::now();
      auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
      timestamp_zero_offset = ms - device_timestamp;
    }
    return (timestamp_zero_offset + device_timestamp) * 0.001;
  }
};

RealSenseGrabber::RealSenseGrabber(const std::string& /*device_uri*/)
: p(new Impl) {}

RealSenseGrabber::~RealSenseGrabber() = default;

inline bool RealSenseGrabber::hasMoreFrames() const {
  return true;
}

bool RealSenseGrabber::grabFrame(cv::OutputArray _color) {
  if (_color.kind() != cv::_InputArray::MAT)
    BOOST_THROW_EXCEPTION(GrabberException("Grabbing only into cv::Mat"));

  _color.create(p->color_image_resolution.height, p->color_image_resolution.width, CV_8UC3);
  cv::Mat color = _color.getMat();

  return p->grabFrame(color);
}

void RealSenseGrabber::setAutoWhiteBalanceEnabled(bool state) {
  p->device->set_option(rs::option::color_enable_auto_white_balance, state ? 1.0 : 0.0);
}

void RealSenseGrabber::setAutoExposureEnabled(bool state) {
  p->device->set_option(rs::option::color_enable_auto_exposure, state ? 1.0 : 0.0);
}

void RealSenseGrabber::setExposure(int exposure) {
  p->device->set_option(rs::option::color_exposure, exposure);
}

int RealSenseGrabber::getExposure() const {
  return p->device->get_option(rs::option::color_exposure);
}

std::pair<int, int> RealSenseGrabber::getExposureRange() const {
  double min, max, step;
  p->device->get_option_range(rs::option::color_exposure, min, max, step);
  return {min, max};
}

void RealSenseGrabber::setGain(int gain) {
  p->device->set_option(rs::option::color_gain, gain);
}

int RealSenseGrabber::getGain() const {
  return p->device->get_option(rs::option::color_gain);
}

std::pair<int, int> RealSenseGrabber::getGainRange() const {
  double min, max, step;
  p->device->get_option_range(rs::option::color_gain, min, max, step);
  return {min, max};
}

std::string RealSenseGrabber::getCameraModelName() const {
  std::string expected_prefix = "Intel RealSense ";
  std::string name = p->device->get_name();
  auto pos = name.find(expected_prefix);
  if (pos == std::string::npos)
    BOOST_THROW_EXCEPTION(GrabberException("Unable to extract camera model name from: " + name));
  name = name.substr(pos + expected_prefix.size());
  boost::algorithm::to_lower(name);
  return name;
}

std::string RealSenseGrabber::getCameraSerialNumber() const {
  return std::string(p->device->get_serial());
}

}  // namespace grabbers

max_stars_repo_name: taketwo/radical

max_issues_repo_name: taketwo/radical

max_forks_repo_name: taketwo/radical


text:
//// Copyright (c) 2018 Silvio Mayolo
//// See LICENSE.txt for licensing details

#ifndef INSTRUCTIONS_HPP
#define INSTRUCTIONS_HPP
#include <deque>
#include <vector>
#include <map>
#include <functional>
#include <boost/variant.hpp>

/// \file
///
/// \brief Data types for managing VM instructions.

class AssemblerLine;

/// The instruction enumeration, containing all of the opcodes for
/// every instruction supported by the Latitude VM. Any value not
/// listed here is not a valid opcode.
enum class Instr : unsigned char {
    MOV = 0x01, PUSH = 0x02, POP = 0x03, GETL = 0x04, GETD = 0x05, ESWAP = 0x06, ECLR = 0x07,
    ESET = 0x08, SYM = 0x09, NUM = 0x0A, INT = 0x0B, FLOAT = 0x0C, NSWAP = 0x0D, CALL = 0x0E,
    XCALL = 0x0F, XCALL0 = 0x10, RET = 0x11, CLONE = 0x12, RTRV = 0x13, RTRVD = 0x14, STR = 0x15,
    SSWAP = 0x16, EXPD = 0x17, MTHD = 0x18, LOAD = 0x19, SETF = 0x1A, PEEK = 0x1B, SYMN = 0x1C,
    CPP = 0x1D, BOL = 0x1E, TEST = 0x1F, BRANCH = 0x20, CCALL = 0x21, CGOTO = 0x22, CRET = 0x23,
    WND = 0x24, UNWND = 0x25, THROW = 0x26, THROQ = 0x27, ADDS = 0x28, ARITH = 0x29, THROA = 0x2A,
    LOCFN = 0x2B, LOCLN = 0x2C, LOCRT = 0x2D, NRET = 0x2E, UNTR = 0x2F, CMPLX = 0x30, YLD = 0x31,
    YLDC = 0x32, DEL = 0x33, ARR = 0x34, DICT = 0x35, XXX = 0x36, GOTO = 0x37, MSWAP = 0x38
};

/// The register enumeration, containing numerical values for
/// referencing every register in an instance of the Latitude VM.
enum class Reg : unsigned char {
    PTR = 0x01, SLF = 0x02, RET = 0x03, LEX = 0x04, DYN = 0x05, ARG = 0x06, STO = 0x07,
    CONT = 0x08, STACK = 0x09, ERR0 = 0x0A, ERR1 = 0x0B, SYM = 0x0C, NUM0 = 0x0D,
    NUM1 = 0x0E, STR0 = 0x0F, STR1 = 0x10, MTHD = 0x11, CPP = 0x12, STRM = 0x13,
    PRCS = 0x14, MTHDZ = 0x15, FLAG = 0x16, WIND = 0x17, HAND = 0x18, LINE = 0x19,
    FILE = 0x1A, TRACE = 0x1B, TRNS = 0x1C, LIT = 0x1D, GTU = 0x1E
};

/// \brief A namespace containing `%%lit` table references.
///
/// This namespace contains constants for referencing the positions in
/// the read-only `%%lit` register, which contains a table of special
/// objects.
namespace Lit {

    /// \brief The index of the Nil object.
    constexpr long NIL    =  0L;

    /// \brief The index of the False object.
    constexpr long FALSE  =  1L;

    /// \brief The index of the True object.
    constexpr long TRUE   =  2L;

    /// \brief The index of the Boolean object.
    constexpr long BOOL   =  3L;

    /// \brief The index of the String object.
    constexpr long STRING =  4L;

    /// \brief The index of the Number object.
    constexpr long NUMBER =  5L;

    /// \brief The index of the Symbol object.
    constexpr long SYMBOL =  6L;

    /// \brief The index of the StackFrame object.
    constexpr long SFRAME =  7L;

    /// \brief The index of the Method object.
    constexpr long METHOD =  8L;

    /// \brief The index of the FileHeader object.
    constexpr long FHEAD  =  9L;

    /// \brief The index of the err object.
    constexpr long ERR    = 10L;

    /// \brief The index of the Array object.
    constexpr long ARRAY  = 11L;

    /// \brief The index of the Dict object.
    constexpr long DICT   = 12L;

    /// \brief The index of the Object object
    constexpr long OBJECT = 13L;

}

/// A function index is fundamentally just an integral value. This
/// type is provided to avoid accidentally treating function indices
/// as ordinary integers and vice versa.
struct FunctionIndex {
    /// The index of the function.
    int index;
};

/// A serial instruction sequence is a sequence of characters.
using SerialInstrSeq = std::deque<unsigned char>;

/// A (non-serial) instruction sequence is a sequence of instructions.
using InstrSeq = std::deque<AssemblerLine>;

/// \brief An argument to an instruction.
///
/// Arguments to instructions can be references to registers, integer
/// values, string values, or indices of functions in the VM.
using RegisterArg = boost::variant<Reg, long, std::string, FunctionIndex>;

/// The singleton InstructionSet instance manages the collection of
/// valid instruction opcodes. It is used by makeRuntimeAssemblerLine
/// to validate the arguments to an instruction and can be used to
/// query the expected argument types.
class InstructionSet {
public:
    /// \brief A validator for determining argument correctness.
    ///
    /// A validator contains criteria for determining whether or not
    /// an argument is correct. It is a 1-ary predicate which takes a
    /// RegisterArg.
    typedef std::function<bool(const RegisterArg&)> Validator;
    /// A ValidList value represents a sequence of Validator values.
    typedef std::vector<Validator> ValidList;
private:
    bool initialized;
    std::map<Instr, ValidList> props;
    static InstructionSet iset;
    void initialize();
    InstructionSet() = default;
public:

    /// Returns the singleton instruction set.
    ///
    /// \return the singleton value
    static InstructionSet& getInstance();

    /// Returns whether or not the instruction set considers the given
    /// opcode to be valid.
    ///
    /// \return whether the opcode is valid or not
    bool hasInstruction(Instr instr);

    /// Returns a sequence of Validator predicates describing all of
    /// the arguments to a given opcode.
    ///
    /// \return the appropriate ValidList value
    ValidList getParams(Instr instr);

};

/// This function is an InstructionSet::Validator representing
/// arguments which are register references.
///
/// \param arg the instruction argument
/// \return whether the argument is a register reference
bool isRegister(const RegisterArg& arg);

/// This function is an InstructionSet::Validator representing
/// arguments which are references to object registers.
///
/// \param arg the instruction arguments
/// \return whether the argument is an object register reference
bool isObjectRegister(const RegisterArg& arg);

/// This function is an InstructionSet::Validator representing
/// arguments which are references to stack registers.
///
/// \param arg the instruction arguments
/// \return whether the argument is an stack register reference
bool isStackRegister(const RegisterArg& arg);

/// This function is an InstructionSet::Validator representing string
/// arguments.
///
/// \param arg the instruction arguments
/// \return whether the argument is a string
bool isStringRegisterArg(const RegisterArg& arg);

/// This function is an InstructionSet::Validator representing integer
/// arguments.
///
/// \param arg the instruction arguments
/// \return whether the argument is an integer
bool isLongRegisterArg(const RegisterArg& arg);

/// This function is an InstructionSet::Validator representing
/// function arguments.
///
/// \param arg the instruction arguments
/// \return whether the argument is a function
bool isAsmRegisterArg(const RegisterArg& arg);

class AssemblerLineArgs;

/// An AssemblerLine is a single instruction as it is being built
/// up. Assembler lines consist of a single opcode and zero or more
/// arguments.
class AssemblerLine {
public:
    /// The type of iterators over the arguments of an AssemblerLine.
    using const_iterator = std::vector<RegisterArg>::const_iterator;
private:
    Instr command;
    std::vector<RegisterArg> args;

    const_iterator iterBegin() const;
    const_iterator iterEnd() const;

public:

    friend class AssemblerLineArgs;

    /// \brief Constructs an empty assembler line.
    AssemblerLine() = default;

    /// \brief Constructs an assembler line with the given opcode.
    ///
    /// \param code the opcode
    AssemblerLine(Instr code);

    /// \brief Gets the opcode for the assembler line.
    ///
    /// \return the opcode
    Instr getCommand() const noexcept;

    /// \brief Sets the opcode for the assembler line.
    ///
    /// \param str the opcode
    void setCommand(Instr str);

    /// \brief Adds an argument to the instruction.
    ///
    /// \param arg the argument
    void addRegisterArg(const RegisterArg& arg);

    /// \brief Removes all of the arguments.
    void clearRegisterArgs();

    /// \brief Returns an iterable construct over the arguments.
    ///
    /// \return an argument iterable
    AssemblerLineArgs arguments() const;

    /// \brief Returns the nth argument of the instruction.
    ///
    /// \param n the index
    /// \return the argument
    RegisterArg argument(int n) const;

    /// \brief Returns the number of arguments.
    ///
    /// \return the argument count
    std::size_t argumentCount() const;

    /// \brief Verifies the integrity of the instruction and its arguments.
    ///
    /// If the instruction is valid and correct, nothing happens.
    /// Otherwise, an exception is thrown.
    ///
    /// \throw AssemblerError in the case of an integrity error
    void validate();

    /// \brief Appends the assembler line onto an instruction sequence.
    ///
    /// \param seq the sequence of instructions
    void appendOnto(InstrSeq& seq) const;

    /// \brief Appends the assembler line onto a serialized
    /// instruction sequence.
    ///
    /// \deprecated Use ::serialize instead
    ///
    /// \param seq the serialized instruction sequence
    [[deprecated]]
    void appendOntoSerial(SerialInstrSeq& seq) const;

};

/// An adapter for AssemblerLine which allows it to be treated as an
/// iterable container by C++ standard library functions. The
/// container will produce a constant iterator which iterates over the
/// arguments of the AssemblerLine. The iterator will be invalidated
/// if any arguments are added or removed or if the argument list is
/// cleared.
class AssemblerLineArgs {
private:
    const AssemblerLine& impl;
public:

    /// Constructs an arguments object.
    ///
    /// \param inner the AssemblerLine object to represent
    AssemblerLineArgs(const AssemblerLine& inner);

    /// \return an iterator to the beginning
    AssemblerLine::const_iterator begin() const;

    /// \return an iterator to the end
    AssemblerLine::const_iterator end() const;

};

bool operator==(FunctionIndex a, FunctionIndex b);

/// Compares two AssemblerLine instances for equality. Two
/// AssemblerLine instances are equal if they contain the same opcode
/// and the same collection of arguments.
///
/// \param a the first line
/// \param b the second line
/// \return whether they are equal
bool operator==(const AssemblerLine& a, const AssemblerLine& b);

/// For efficiency reasons, it is undesirable to pass around methods
/// as sequences of instructions. Thus, all methods in Latitude code
/// are stored in localized translation units, where they can be
/// referenced by a pointer and an index. A translation unit consists
/// of a global sequence of instructions (usually the "top-level" code
/// in a file or module) and an ordered sequence of instruction
/// sequences, which are often (but not necessarily) referenced as
/// methods.
class TranslationUnit {
private:
    std::vector<InstrSeq> methods;
public:

    /// Constructs a default translation unit consisting of no code
    /// and no methods.
    TranslationUnit();

    /// Constructs a translation unit consisting of the given
    /// top-level code and no methods.
    TranslationUnit(const InstrSeq& seq);

    /// Returns the translation unit's top-level instruction sequnce.
    ///
    /// \return the top-level sequence of instructions
    InstrSeq& instructions();

    /// Returns the nth method in the translation unit. No bounds
    /// checking is performed. It is the caller's responsibility
    /// to ensure that the argument to this method is between 0 and
    /// methodCount().
    ///
    /// \param index the index of the method
    /// \return the method itself
    InstrSeq& method(int index);

    /// Returns the number of methods in the translation unit.
    ///
    /// \return the method count
    int methodCount();

    /// Adds a method to the translation unit. The argument will be
    /// copied into the translation unit.
    ///
    /// \param mthd the method to add
    /// \return the index of the method
    FunctionIndex pushMethod(const InstrSeq& mthd);

    /// Adds a method to the translation unit, using move semantics.
    ///
    /// \param mthd the method to add
    /// \return the index of the method
    FunctionIndex pushMethod(InstrSeq&& mthd);

};

/// A smart pointer to a translation unit.
using TranslationUnitPtr = std::shared_ptr<TranslationUnit>;

/// A method is referenced by a Method object, which consists of a
/// pointer to a translation unit and an index within that unit.
class Method {
private:
    TranslationUnitPtr unit;
    FunctionIndex ind;
public:

    /// Default-constructs a method. This constructor should be used
    /// sparingly, as it creates a "null" method object which cannot
    /// be called.
    Method();

    /// Constructs a callable method object.
    ///
    /// \param ptr the translation unit in which the method code resides
    /// \param index the position in the translation unit of the code
    Method(const TranslationUnitPtr& ptr, FunctionIndex index);

    /// Retrieves the sequence of instructions belonging to this method.
    ///
    /// \return the method's instruction sequence
    InstrSeq& instructions();

    /// Returns the size of the method instruction sequence.
    ///
    /// \return the size of the instruction sequence
    size_t size();

    /// Retrieves a pointer to the translation unit to which this
    /// method belongs.
    ///
    /// \return the translation unit to which the method belongs
    TranslationUnitPtr translationUnit();

    /// Returns the index within translationUnit() where this method
    /// can be found.
    ///
    /// \return the function index within the translation unit
    FunctionIndex index();

    friend bool operator==(Method a, Method b);

};

bool operator==(Method a, Method b);

/// For efficiency reasons, it is undesirable to store methods
/// directly. Therefore, a MethodSeek instance stores a sequence of
/// instructions, not directly, but by reference to a translation
/// unit.
class MethodSeek {
private:
    unsigned long pos;
    unsigned long _size;
    Method method;
public:

    /// Constructs a nullary MethodSeek object. It is not safe to
    /// access the fields of a nullary MethodSeek object.
    MethodSeek();

    /// Constructs a MethodSeek which points to the specified method.
    ///
    /// \param m a method
    MethodSeek(Method m);

    /// Returns the position of the MethodSeek object within the
    /// InstrSeq data.
    ///
    /// \return the position
    unsigned long position();

    /// Advances the MethodSeek's position by an integer amount, which
    /// must be positive.
    ///
    /// \param val the number by which to advance the position
    void advancePosition(unsigned long val);

    /// Returns the size of the instructions() sequence.
    ///
    /// \return the size
    unsigned long size();

    /// Returns whether the sequence is at its end. Specifically, this
    /// checks whether or not size() is equal to position().
    ///
    /// \return whether or not the sequence is at its end
    bool atEnd();

    /// Reads a single long argument from the instruction
    /// sequence. The behavior is undefined if the given argment is
    /// not a long integer.
    ///
    /// \param n the position of the argument within the current instruction
    /// \return the long argument
    long readLong(int n);

    /// Reads a single string argument from the instruction
    /// sequence. The behavior is undefined if the given argment is
    /// not a string.
    ///
    /// \param n the position of the argument within the current instruction
    /// \return the string argument
    std::string readString(int n);

    /// Reads a single register argument from the instruction
    /// sequence. The behavior is undefined if the given argment is
    /// not a register.
    ///
    /// \param n the position of the argument within the current instruction
    /// \return the register argument
    Reg readReg(int n);

    /// Retrieves the opcode of the current instruction in the
    /// sequence.
    ///
    /// \return the instruction opcode
    Instr readInstr();

    /// Reads a single function argument from the instruction
    /// sequence. The behavior is undefined if the given argment is
    /// not a function index.
    ///
    /// \param n the position of the argument within the current instruction
    /// \return the function argument
    FunctionIndex readFunction(int n);

    /// Returns the full sequence of instructions representing the
    /// method.
    ///
    /// \return the instruction sequence
    InstrSeq& instructions();

};

#endif // INSTRUCTIONS_HPP

max_stars_repo_name: Mercerenies/latitude

max_issues_repo_name: Mercerenies/latitude

max_forks_repo_name: Mercerenies/proto-lang


text:
/*
Copyright (c) Members of the EGEE Collaboration. 2004.
See http://www.eu-egee.org/partners/ for details on the
copyright holders.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/*
 * File: listmatch.cpp
 * Author: Marco Pappalardo <Marco.Pappalardo@ct.infn.it>
 * Author: Cinzia Di Giusto <Cinzia.DiGiusto@cnaf.infn.it>
 * Author: Francesco Giacomini
 * Author: Francesco Prelz
 */

#include <iostream>
#include <fstream>

#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>

#include "listmatch.h"
#include "glite/wmsutils/classads/classad_utils.h"
#include "glite/wms/common/utilities/scope_guard.h"

#include "glite/wms/helper/Helper.h"
#include "glite/wms/helper/exceptions.h"

namespace utilities = glite::wms::common::utilities;
namespace ca = glite::wmsutils::classads;

namespace glite {
namespace wms {
namespace manager {
namespace server {

bool match(
  classad::ClassAd const& jdl,
  std::string const& result_file,
  int number_of_results,
  bool include_brokerinfo
)
{
  if (result_file.empty() || result_file[0] != '/') {
    return false;
  }

  std::auto_ptr<classad::ClassAd> result;

  try {

    classad::ClassAd ad(jdl);
    ad.InsertAttr("include_brokerinfo", include_brokerinfo);
    ad.InsertAttr("number_of_results", number_of_results);
    result.reset(glite::wms::helper::Helper("MatcherHelper").resolve(&ad));

    classad::ExprTree *et = result->Lookup ("match_result");
    assert(ca::is_expression_list(et));
    classad::ExprList& match_result = *static_cast<classad::ExprList*>(et);

    if (match_result.size() != 0) {
      std::vector<classad::ExprTree*> list;
      match_result.GetComponents(list);

      std::vector<classad::ExprTree*> newlist;
      if (number_of_results == -1) {
        number_of_results = match_result.size();
      }

      int const n_results = std::min(number_of_results, match_result.size());
      for (int i = 0; i < n_results; ++i) {
        assert(ca::is_classad(list[i]));
        std::auto_ptr<classad::ExprTree> element(list[i]->Copy());

        if (!include_brokerinfo) {

          //translate the answer in this format
          /* [
           *   reason = ok;
           *   match_result = {"host1,rank1", "host2,rank2", ...}
           * ]
           */
          classad::ClassAd* ca = static_cast<classad::ClassAd*>(element.get());
          std::string host = ca::evaluate_attribute(*ca, "ce_id");
          double rank = ca::evaluate_attribute(*ca, "rank");

          classad::Value value;
          value.SetStringValue(host + ',' + boost::lexical_cast<std::string>(rank));

          element.reset(classad::Literal::MakeLiteral(value));
        }
        newlist.push_back(element.release());
      }

      result->Insert("match_result", classad::ExprList::MakeExprList(newlist));
    }
  } catch (glite::wms::helper::HelperError const& e) {
    // We need to chime into the communication pipe in this case.
    result.reset(new classad::ClassAd);
    result->InsertAttr("reason", std::string("error accessing broker helper"));
    result->InsertAttr("match_result", new classad::ExprList);
  }

  classad::PrettyPrint result_unparser;
  std::string          result_string;
  result_unparser.Unparse(result_string, result.get());

  int const fd = open(result_file.c_str(), O_WRONLY | O_NONBLOCK);
  if (fd == -1) {
    return false;
  }
  utilities::scope_guard close_fd(boost::bind(::close, fd));

  int const max_retries = 7;
  int retry_count = 0;
  int backoff_time = 1;
  int const write_size = result_string.size();
  int written_size = 0;
  char const* const c_result_string = result_string.c_str();

  while (written_size != write_size) {
    int n_write(
      write(fd, c_result_string + written_size, write_size - written_size)
    );

    if (n_write > 0 && n_write <= (write_size - written_size)) {
      written_size += n_write;
      backoff_time = 1;
      retry_count = 0;
    } else if (n_write == 0) {
      sleep(backoff_time);
      backoff_time *= 2;
      ++retry_count;
    } else {
      if (errno == EAGAIN && retry_count < max_retries) {
        sleep(backoff_time);
        backoff_time *= 2;
        ++retry_count;
      } else {
        break;
      }
    }
  }

  return written_size == write_size;
}

}}}} // glite::wms::manager::server

max_stars_repo_name: italiangrid/wms

max_issues_repo_name: italiangrid/wms

max_forks_repo_name: italiangrid/wms


text:
/*=============================================================================
    Copyright (c) 2001-2007 Joel de Guzman

    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)
==============================================================================*/
#if !defined(BOOST_SPIRIT_META_GRAMMAR_FEB_05_2007_0320PM)
#define BOOST_SPIRIT_META_GRAMMAR_FEB_05_2007_0320PM

#include <boost/spirit/home/support/modifier.hpp>
#include <boost/spirit/home/support/placeholders.hpp>
#include <boost/spirit/home/support/meta_grammar.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/iso8859_1.hpp>
#include <boost/spirit/home/support/ascii.hpp>
#include <boost/spirit/home/support/standard.hpp>
#include <boost/spirit/home/support/standard_wide.hpp>
#include <boost/utility/enable_if.hpp>

namespace boost { namespace spirit { namespace qi
{
    ///////////////////////////////////////////////////////////////////////////
    // forwards
    ///////////////////////////////////////////////////////////////////////////
    struct lexeme_director;
    struct omit_director;
    struct raw_director;
    struct main_meta_grammar;

    template <typename Expr, typename Enable>
    struct is_valid_expr;

    template <typename Expr, typename Enable>
    struct expr_transform;

    ///////////////////////////////////////////////////////////////////////////
    // directive meta-grammars
    ///////////////////////////////////////////////////////////////////////////
    struct directive_meta_grammar
      : proto::or_<
            meta_grammar::deep_directive_meta_grammar<
                spirit::char_class::no_case_tag<proto::_>
              , main_meta_grammar
            >
          , meta_grammar::binary_rule_rhs<
                qi::domain, proto::tag::subscript, lexeme_director
              , proto::terminal<tag::lexeme>, main_meta_grammar
            >
          , meta_grammar::binary_rule_rhs<
                qi::domain, proto::tag::subscript, omit_director
              , proto::terminal<tag::omit>, main_meta_grammar
            >
          , meta_grammar::binary_rule_rhs<
                qi::domain, proto::tag::subscript, raw_director
              , proto::terminal<tag::raw>, main_meta_grammar
            >
        >
    {};

    ///////////////////////////////////////////////////////////////////////////
    //  These specializations non-intrusively hooks into the RD meta-grammar.
    //  (see qi/meta_grammar.hpp)
    ///////////////////////////////////////////////////////////////////////////
    template <typename Expr>
    struct is_valid_expr<Expr
      , typename enable_if<proto::matches<Expr, directive_meta_grammar> >::type>
      : mpl::true_
    {
    };

    template <typename Expr>
    struct expr_transform<Expr
      , typename enable_if<proto::matches<Expr, directive_meta_grammar> >::type>
      : mpl::identity<directive_meta_grammar>
    {
    };
}}}

#endif

max_stars_repo_name: jaredhoberock/gotham

max_issues_repo_name: jaredhoberock/gotham

max_forks_repo_name: jaredhoberock/gotham


text:
#ifndef DART_NEURAL_WRT_HPP_
#define DART_NEURAL_WRT_HPP_

#include <memory>

#include <Eigen/Dense>

#include "dart/math/MathTypes.hpp"

namespace dart {
namespace simulation {
class World;
}

namespace dynamics {
class Skeleton;
}

namespace neural {

class WithRespectToPosition;
class WithRespectToVelocity;
class WithRespectToForce;

class WithRespectTo
{
public:
  virtual ~WithRespectTo();

  /// This returns this WRT from the world as a vector
  virtual Eigen::VectorXs get(simulation::World* world) = 0;

  /// This returns this WRT from a skeleton as a vector
  virtual Eigen::VectorXs get(dynamics::Skeleton* skel) = 0;

  /// This sets the world's state based on our WRT
  virtual void set(simulation::World* world, Eigen::VectorXs value) = 0;

  /// This sets the skeleton's state based on our WRT
  virtual void set(dynamics::Skeleton* skel, Eigen::VectorXs value) = 0;

  /// This gives the dimensions of the WRT in a whole world
  virtual int dim(simulation::World* world) = 0;

  /// This gives the dimensions of the WRT in a single skeleton
  virtual int dim(dynamics::Skeleton* skel) = 0;

  /// This gives a vector of upper bound values for this WRT, given state in the
  /// world
  virtual Eigen::VectorXs upperBound(simulation::World* world) = 0;

  /// This gives a vector of lower bound values for this WRT, given state in the
  /// world
  virtual Eigen::VectorXs lowerBound(simulation::World* world) = 0;

  static WithRespectToPosition* POSITION;
  static WithRespectToVelocity* VELOCITY;
  static WithRespectToForce* FORCE;
};

class WithRespectToPosition : public WithRespectTo
{
public:
  WithRespectToPosition();

  /// This returns this WRT from the world as a vector
  Eigen::VectorXs get(simulation::World* world) override;

  /// This returns this WRT from a skeleton as a vector
  Eigen::VectorXs get(dynamics::Skeleton* skel) override;

  /// This sets the world's state based on our WRT
  void set(simulation::World* world, Eigen::VectorXs value) override;

  /// This sets the skeleton's state based on our WRT
  void set(dynamics::Skeleton* skel, Eigen::VectorXs value) override;

  /// This gives the dimensions of the WRT
  int dim(simulation::World* world) override;

  /// This gives the dimensions of the WRT in a single skeleton
  int dim(dynamics::Skeleton* skel) override;

  /// This gives a vector of upper bound values for this WRT, given state in the
  /// world
  Eigen::VectorXs upperBound(simulation::World* world) override;

  /// This gives a vector of lower bound values for this WRT, given state in the
  /// world
  Eigen::VectorXs lowerBound(simulation::World* world) override;
};

class WithRespectToVelocity : public WithRespectTo
{
public:
  WithRespectToVelocity();

  /// This returns this WRT from the world as a vector
  Eigen::VectorXs get(simulation::World* world) override;

  /// This returns this WRT from a skeleton as a vector
  Eigen::VectorXs get(dynamics::Skeleton* skel) override;

  /// This sets the world's state based on our WRT
  void set(simulation::World* world, Eigen::VectorXs value) override;

  /// This sets the skeleton's state based on our WRT
  void set(dynamics::Skeleton* skel, Eigen::VectorXs value) override;

  /// This gives the dimensions of the WRT
  int dim(simulation::World* world) override;

  /// This gives the dimensions of the WRT in a single skeleton
  int dim(dynamics::Skeleton* skel) override;

  /// This gives a vector of upper bound values for this WRT, given state in the
  /// world
  Eigen::VectorXs upperBound(simulation::World* world) override;

  /// This gives a vector of lower bound values for this WRT, given state in the
  /// world
  Eigen::VectorXs lowerBound(simulation::World* world) override;
};

class WithRespectToForce : public WithRespectTo
{
public:
  WithRespectToForce();

  /// This returns this WRT from the world as a vector
  Eigen::VectorXs get(simulation::World* world) override;

  /// This returns this WRT from a skeleton as a vector
  Eigen::VectorXs get(dynamics::Skeleton* skel) override;

  /// This sets the world's state based on our WRT
  void set(simulation::World* world, Eigen::VectorXs value) override;

  /// This sets the skeleton's state based on our WRT
  void set(dynamics::Skeleton* skel, Eigen::VectorXs value) override;

  /// This gives the dimensions of the WRT
  int dim(simulation::World* world) override;

  /// This gives the dimensions of the WRT in a single skeleton
  int dim(dynamics::Skeleton* skel) override;

  /// This gives a vector of upper bound values for this WRT, given state in the
  /// world
  Eigen::VectorXs upperBound(simulation::World* world) override;

  /// This gives a vector of lower bound values for this WRT, given state in the
  /// world
  Eigen::VectorXs lowerBound(simulation::World* world) override;
};

} // namespace neural
} // namespace dart

#endif


#include"commondomfeatures.h++"
#include<xercesc/util/PlatformUtils.hpp>
#include<xercesc/util/XMLUniDefs.hpp>
#include<iostream>
#include <libstreamcon/throw.h++>
#include <boost/thread/detail/singleton.hpp>
#include <libxftp/xercesstrings.h++>
using namespace xercesc;
xftp::xml::CommonDOMFeatures::CommonDOMFeatures()
{

	XMLPlatformUtils::Initialize();
	Implementation= // Get first registered implementation
					// that has desired properties
					// (currently only availble)
			DOMImplementationRegistry::getDOMImplementation(
						(XMLCh[]){chLatin_L,chLatin_S,chNull});

	Serializer.reset(
		((DOMImplementationLS*) // Serializer will be used to transform
								 // DOM trees into textual XML documents
			Implementation)->createDOMWriter());

    if (Serializer->canSetFeature(//basic serializer setup
		xercesc::XMLUni::fgDOMWRTDiscardDefaultContent, true))
        Serializer->setFeature(
		xercesc::XMLUni::fgDOMWRTDiscardDefaultContent, true);

    if (Serializer->canSetFeature(
		xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true))
		Serializer->setFeature(
		xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true);

//	std::cerr<<"xmlinit"<<std::endl;
}

std::tr1::shared_ptr<xercesc::DOMWriter>
		xftp::xml::CommonDOMFeatures::getSerializer()
{
	return Serializer;
}

xftp::xml::CommonDOMFeatures::~CommonDOMFeatures()
{
//	std::cerr<<"xmlterm"<<std::endl;
	std::tr1::shared_ptr<xercesc::DOMWriter> xdw;
	Serializer=xdw;
	XMLPlatformUtils::Terminate();
}

const XMLCh* xftp::xml::CommonDOMFeatures::GetClientNamespaceURI()
{
	static const XMLCh uri[] = {chLatin_c,chLatin_l,chLatin_i,
								chLatin_e,chLatin_n,chLatin_t,chNull};
	return uri;
}

const XMLCh* xftp::xml::CommonDOMFeatures::GetServerNamespaceURI()
{
	static const XMLCh uri[] = {chLatin_s,chLatin_e,chLatin_r,
								chLatin_v,chLatin_e,chLatin_r,chNull};
	return uri;

}

DOMDocument * xftp::xml::CommonDOMFeatures::createDocument()
{
	return Implementation->createDocument ();
}

xftp::xml::CommonDOMFeatures & xftp::xml::CommonDOMFeatures::Instance()
{
	return boost::detail::thread::singleton
				<xml::CommonDOMFeatures>::instance();
}
const XMLCh* xftp::xml::CommonDOMFeatures::GetElementNamespace(const xercesc::DOMElement & e)
{
	const XMLCh* NSU =  e.getNamespaceURI();

	const XMLCh * Result;
	const xercesc::DOMElement * pe = &e;
	//try getting xmlns for this element
	while (XMLString::equals((XMLCh[]){chNull},
			 (Result = pe->getAttributeNS(NSU,const_cast<XMLCh*>((XMLCh[])
				 {chLatin_x,chLatin_m,chLatin_l,chLatin_n,chLatin_s,chNull})) )))
	{//if failedm try parent
		pe=dynamic_cast<xercesc::DOMElement*>(pe->getParentNode());
		if (not pe) // dynamic cast fails if there is no parent element (i.e. pe
			// represents root element)
			THROW(GetNamespaceFailed);
	}
	return Result;
}

void xftp::xml::CommonDOMFeatures::SetElementNamespace(xercesc::DOMElement & e,const XMLCh* n)
{
	e.setAttribute((XMLCh[]){chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull},n);
}

void xftp::xml::CommonDOMFeatures::NormalizeElementNamespaces(xercesc::DOMElement & e)
{

	xercesc::DOMElement * pe = &e;
	const XMLCh* NSU =  e.getNamespaceURI();

	DOMNodeList* children = pe->getChildNodes();
	const  XMLSize_t nodeCount = children->getLength();

	for( XMLSize_t i = 0; i < nodeCount; ++i )
	{
		DOMElement* currentNode = dynamic_cast<DOMElement*>
			(children->item(i));
		if (not currentNode) continue;

		const XMLCh* ceNS =
			currentNode->getAttributeNS(NSU,const_cast<XMLCh*>((XMLCh[])
				{chLatin_x,chLatin_m,chLatin_l,chLatin_n,chLatin_s,chNull}));
		const XMLCh* peNS =
			pe->getAttributeNS(NSU,const_cast<XMLCh*>((XMLCh[])
				{chLatin_x,chLatin_m,chLatin_l,chLatin_n,chLatin_s,chNull}));
//		std::cout << "Fixing namespace " << toNative(ceNS) << ',' << toNative(peNS) << std::endl;
		if (ceNS)
		{
			if (XMLString::equals(peNS,(XMLCh[]){chNull}))
				pe->setAttribute((XMLCh[]){chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull},ceNS);
			else if (not XMLString::equals(ceNS,peNS))
				continue;
			currentNode->removeAttribute((XMLCh[]){chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull});
		}
	}
}


text:
#pragma once
#include <fmt/format.h>
#include "network/base/memory_stream.hpp"
#include "network/util/net.hpp"
#include "serializer.hpp"
#include "deserializer.hpp"
#include <thrift/transport/TTransportException.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/protocol/TCompactProtocol.h>
#include <thrift/TBase.h>

#include <boost/make_shared.hpp>
#include <boost/smart_ptr/enable_shared_from_this.hpp>

namespace cytx
{
    using namespace apache::thrift;
    using namespace apache::thrift::protocol;
    using namespace apache::thrift::transport;

    struct thrift_serialize_adapter {};
    struct thrift_deserialize_adapter {};

    template<>
    class Serializer<thrift_serialize_adapter>
    {
        using adapter_t = memory_stream;
    public:
        Serializer()
        {
        }

        ~Serializer()
        {
        }

        template<typename T>
        auto Serialize(T& t) -> std::enable_if_t<is_tuple_v<T>, memory_stream>
        {
            auto mem_buf = boost::make_shared<TMemoryBuffer>();
            auto compct_proto = boost::make_shared<TCompactProtocol>(mem_buf);
            std::get<0>(t).write(compct_proto.get());

            uint32_t length = 0;
            uint8_t* body_buf_ptr = nullptr;
            mem_buf->getBuffer(&body_buf_ptr, &length);

            memory_stream gos(length);
            gos.write_binary((char*)body_buf_ptr, length);
            return gos;
        }

        template<typename T>
        auto Serialize(T& t) -> std::enable_if_t<!is_tuple_v<T>, memory_stream>
        {
            auto mem_buf = boost::make_shared<TMemoryBuffer>();
            auto compct_proto = boost::make_shared<TCompactProtocol>(mem_buf);
            t.write(compct_proto.get());

            uint32_t length = 0;
            uint8_t* body_buf_ptr = nullptr;
            mem_buf->getBuffer(&body_buf_ptr, &length);

            memory_stream gos(length);
            gos.write_binary((char*)body_buf_ptr, length);
            return gos;
        }

        template<typename T>
        auto Serialize(memory_stream& gos, T& t) -> std::enable_if_t<is_tuple_v<T>>
        {
            auto mem_buf = boost::make_shared<TMemoryBuffer>();
            auto compct_proto = boost::make_shared<TCompactProtocol>(mem_buf);
            std::get<0>(t).write(compct_proto.get());

            uint32_t length = 0;
            uint8_t* body_buf_ptr = nullptr;
            mem_buf->getBuffer(&body_buf_ptr, &length);

            gos.write_binary((char*)body_buf_ptr, length);
        }

        template<typename T>
        auto Serialize(memory_stream& gos, T& t) -> std::enable_if_t<!is_tuple_v<T>>
        {
            auto mem_buf = boost::make_shared<TMemoryBuffer>();
            auto compct_proto = boost::make_shared<TCompactProtocol>(mem_buf);
            t.write(compct_proto.get());

            uint32_t length = 0;
            uint8_t* body_buf_ptr = nullptr;
            mem_buf->getBuffer(&body_buf_ptr, &length);

            gos.write_binary((char*)body_buf_ptr, length);
        }
    };

    template<typename OtherTuple>
    class DeSerializer<thrift_deserialize_adapter, OtherTuple> : public BaseDeSerializer<thrift_deserialize_adapter, OtherTuple>
    {
        using base_t = BaseDeSerializer<thrift_deserialize_adapter, OtherTuple>;
        using gos_t = memory_stream;
    public:
        DeSerializer(gos_t& gos)
            : base_t()
            , gos_(gos)
        {
        }

        DeSerializer(OtherTuple&& t, gos_t& gos)
            : base_t(std::forward<OtherTuple>(t))
            , gos_(gos)
        {
        }

        ~DeSerializer()
        {
        }

        gos_t& get_gos() { return gos_; }

        template<typename T>
        void DeSerialize(T& t)
        {
            ReadObject(t);
        }

        template<typename T>
        auto GetTuple()->std::enable_if_t < 0 < std::tuple_size<T>::value, T >
        {
            return make<T, 0>(std::true_type{}, std::tuple<>{});
        }

        template<typename T>
        auto GetTuple()->std::enable_if_t < 0 == std::tuple_size<T>::value, T >
        {
            return std::tuple<>{};
        }

    private:
        template <typename T, size_t Is, typename ReturnT>
        auto make(std::true_type, ReturnT&& t)
        {
            using value_type = std::conditional_t<(Is + 1) == std::tuple_size<T>::value, std::false_type, std::true_type>;
            using elem_t = std::tuple_element_t<Is, T>;
            return make<T, Is + 1>(value_type{}, std::tuple_cat(t, std::tuple<elem_t>(get_tuple_elem<elem_t>())));
        }

        template <typename T, size_t Is, typename ReturnT>
        auto make(std::false_type, ReturnT&& t)
        {
            return t;
        }

        template<typename T>
        auto get_tuple_elem() -> std::enable_if_t<tuple_contains<T, OtherTuple>::value, T>
        {
            return std::get<tuple_index<T, OtherTuple>::value>(tuple_);
        }

        template<typename T>
        auto get_tuple_elem() -> std::enable_if_t<!tuple_contains<T, OtherTuple>::value, T>
        {
            T t{};
            ReadObject(t);
            return std::move(t);
        }

        template<typename T>
        auto ReadObject(T& t)
        {
            auto membuffer = boost::make_shared<TMemoryBuffer>();
            auto protocol = boost::make_shared<TCompactProtocol>(membuffer);

            membuffer->resetBuffer((uint8_t*)gos_.rd_ptr(), gos_.length());
            t.read(protocol.get());
        }
    private:
        memory_stream& gos_;
    };
}

max_stars_repo_name: hbccdf/network-core

max_issues_repo_name: hbccdf/network-core

max_forks_repo_name: hbccdf/network-core


text:
// MIT License
//
// Copyright (c) 2018 Michal Siedlaczek
//
// 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.

//! \file
//! \author Michal Siedlaczek
//! \copyright MIT License

#pragma once

#include <iterator>
#include <sstream>
#include <vector>

#include <boost/iterator.hpp>

#include <irkit/coding.hpp>
#include <irkit/coding/stream_vbyte.hpp>
#include <irkit/coding/vbyte.hpp>
#include <irkit/index/block.hpp>
#include <irkit/index/types.hpp>
#include <irkit/memoryview.hpp>
#include <irkit/sgnd.hpp>

namespace irk {

template<class D, class P>
class raw_posting {
    D document_{};
    P payload_{};

public:
    raw_posting() = default;
    raw_posting(D document, P payload) noexcept
        : document_(document), payload_(payload)
    {}
    raw_posting(const raw_posting&) = default;
    raw_posting(raw_posting&&) noexcept = default;
    raw_posting& operator=(const raw_posting&) = default;
    raw_posting& operator=(raw_posting&&) noexcept = default;
    ~raw_posting() = default;

    const D& document() const { return document_; }
    const P& payload() const { return payload_; }
};

template<class Iterator>
class raw_iterator : public boost::iterator_facade<
                         raw_iterator<Iterator>,
                         typename std::iterator_traits<Iterator>::value_type,
                         boost::forward_traversal_tag> {
public:
    using difference_type = std::ptrdiff_t;
    using value_type = typename std::iterator_traits<Iterator>::value_type;
    using reference = value_type&;

    raw_iterator(const raw_iterator&) = default;
    raw_iterator(raw_iterator&&) noexcept = default;
    raw_iterator& operator=(const raw_iterator&) = default;
    raw_iterator& operator=(raw_iterator&&) noexcept = default;
    ~raw_iterator() = default;

    raw_iterator(index::term_id_t term_id, Iterator pos, Iterator end)
        : term_id_(term_id), pos_(std::move(pos)), end_(std::move(end))
    {}

    constexpr auto advance_to(value_type val) -> raw_iterator&
    {
        while (pos_ != end_ && *pos_ < val) {
            ++pos_;
        }
        return *this;
    };

    [[nodiscard]] constexpr auto next_ge(value_type val) -> raw_iterator
    {
        raw_iterator next(*this);
        next.advance_to(val);
        return next;
    };

    const index::term_id_t& term_id() const { return term_id_; }

private:
    friend class boost::iterator_core_access;
    void increment() { ++pos_; }
    void advance(difference_type n) { std::advance(pos_, n); }
    bool equal(const raw_iterator& other) const { return pos_ == other.pos_; }
    const value_type& dereference() const { return *pos_; }

    void finish() { pos_ = end_; }

    index::term_id_t term_id_{};
    Iterator pos_{};
    Iterator end_{};
};

template<class T>
class raw_inverted_list {
public:
    using size_type = int64_t;
    using value_type = T;

    raw_inverted_list() = default;

    template<class Iterator>
    raw_inverted_list(index::term_id_t term_id, Iterator first, Iterator last)
        : term_id_(term_id), elements_(first, last)
    {}

    template<class Iterator, class UnaryFunction>
    raw_inverted_list(
        index::term_id_t term_id,
        Iterator first,
        Iterator last,
        UnaryFunction f)
        : term_id_(term_id)
    {
        std::transform(first, last, std::back_inserter(elements_), f);
    }

    raw_inverted_list(index::term_id_t term_id, std::vector<T> elements)
        : term_id_(term_id), elements_(std::move(elements))
    {}

    auto begin() const { return elements_.cbegin(); };
    auto end() const { return elements_.cend(); };

    auto lookup(value_type id) const { return begin().nextgeq(id); };
    int64_t size() const { return irk::sgnd(elements_.size()); }
    const index::term_id_t& term_id() const { return term_id_; }

private:
    index::term_id_t term_id_{};
    std::vector<T> elements_;
};

template<class Codec>
using raw_document_list = raw_inverted_list<index::document_t>;

template<class Payload, class Codec>
using raw_payload_list = raw_inverted_list<Payload>;

}  // namespace irk

max_stars_repo_name: elshize/irkit

max_issues_repo_name: elshize/irkit

max_forks_repo_name: elshize/irkit


text:
/*
 *
 * Copyright (c) 2002, 2003 Kresimir Fresl, Toon Knapen and Karl Meerbergen
 * Copyright (c) 2008 Markus Rickert
 *
 * 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)
 *
 * KF acknowledges the support of the Faculty of Civil Engineering,
 * University of Zagreb, Croatia.
 *
 */

#ifndef BOOST_NUMERIC_BINDINGS_TRAITS_C_ARRAY2_H
#define BOOST_NUMERIC_BINDINGS_TRAITS_C_ARRAY2_H

#include <boost/numeric/bindings/traits/config.hpp>

#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS

#include <boost/numeric/bindings/traits/c_array.hpp>
#include <boost/numeric/bindings/traits/matrix_traits.hpp>

namespace boost { namespace numeric { namespace bindings { namespace traits {

  // built-in array as matrix (nx1)
  template <typename T, std::size_t N, typename V>
  struct matrix_detail_traits<T[N], V>
  {
#ifndef BOOST_NUMERIC_BINDINGS_NO_SANITY_CHECK
    BOOST_STATIC_ASSERT(
      (boost::is_same<
         T[N],
         typename boost::remove_const<V>::type
       >::value) );
#endif

    typedef T identifier_type [N];
    typedef V matrix_type;
    typedef general_t matrix_structure;
    typedef column_major_t ordering_type;

    typedef T value_type;
    typedef typename default_vector_traits< V, T >::pointer pointer;

    static pointer storage (matrix_type& v) {
      return vector_traits<matrix_type>::storage (v);
    }
    static std::ptrdiff_t num_rows (matrix_type& v) { return N; }
    static std::ptrdiff_t num_columns (matrix_type&) { return 1; }
    static std::ptrdiff_t storage_size (matrix_type& v) { return N; }
//    static std::ptrdiff_t stride1 (matrix_type& v) { return vector_traits<V>::stride (v); }
//    static std::ptrdiff_t stride2 (matrix_type&) { return 1; }
    static std::ptrdiff_t leading_dimension (matrix_type& v) { return N; }
  };

}}}}

#else // BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS

#error with your compiler plain C array cannot be used in bindings

#endif // BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS

#endif // BOOST_NUMERIC_BINDINGS_TRAITS_C_ARRAY2_H

max_stars_repo_name: diku-dk/PROX

max_issues_repo_name: jdsika/holy

max_forks_repo_name: jdsika/holy