<commit_before>/*ckwg +5
 * Copyright 2011-2012 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include "config.h"

#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
#include <boost/none.hpp>

#include <algorithm>
#include <sstream>

/**
 * \file config.cxx
 *
 * \brief Implementation of \link vistk::config configuration\endlink in the pipeline.
 */

namespace vistk
{

config::key_t const config::block_sep = key_t(":");
config::key_t const config::global_value = key_t("_global");

static bool does_not_begin_with(config::key_t const& key, config::key_t const& name);
static config::key_t strip_block_name(config::key_t const& key);

config_t
config
::empty_config(key_t const& name)
{
  return config_t(new config(name, config_t()));
}

config
::~config()
{
}

config_t
config
::subblock(key_t const& key) const
{
  config_t conf = empty_config(key);

  BOOST_FOREACH (key_t const& key_name, available_values())
  {
    if (does_not_begin_with(key_name, key))
    {
      continue;
    }

    key_t const stripped_key_name = strip_block_name(key_name);

    conf->set_value(stripped_key_name, get_value(key_name));
  }

  return conf;
}

config_t
config
::subblock_view(key_t const& key)
{
  return config_t(new config(key, shared_from_this()));
}

void
config
::set_value(key_t const& key, value_t const& value)
{
  if (m_parent)
  {
    m_parent->set_value(m_name + block_sep + key, value);
  }
  else
  {
    if (is_read_only(key))
    {
      value_t const current_value = get_value<value_t>(key, value_t());

      throw set_on_read_only_value_exception(key, current_value, value);
    }

    m_store[key] = value;
  }
}

void
config
::unset_value(key_t const& key)
{
  if (m_parent)
  {
    m_parent->unset_value(m_name + block_sep + key);
  }
  else
  {
    if (is_read_only(key))
    {
      value_t const current_value = get_value<value_t>(key, value_t());

      throw unset_on_read_only_value_exception(key, current_value);
    }

    store_t::iterator const i = m_store.find(key);

    if (i == m_store.end())
    {
      throw no_such_configuration_value_exception(key);
    }

    m_store.erase(i);
  }
}

bool
config
::is_read_only(key_t const& key) const
{
  ro_list_t::iterator i = m_ro_list.find(key);

  return (i != m_ro_list.end());
}

void
config
::mark_read_only(key_t const& key)
{
  m_ro_list.insert(key);
}

void
config
::merge_config(config_t conf)
{
  BOOST_FOREACH (store_t::value_type const& value, conf->m_store)
  {
    key_t const& key = value.first;
    value_t const& val = value.second;

    set_value(key, val);
  }
}

config::keys_t
config
::available_values() const
{
  keys_t keys;

  if (m_parent)
  {
    keys = m_parent->available_values();

    keys_t::iterator const i = std::remove_if(keys.begin(), keys.end(), boost::bind(does_not_begin_with, _1, m_name));

    keys.erase(i, keys.end());

    std::for_each(keys.begin(), keys.end(), strip_block_name);
  }
  else<commit_msg>Fix list of available keys from a subblock view<commit_after>/*ckwg +5
 * Copyright 2011-2012 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include "config.h"

#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
#include <boost/none.hpp>

#include <algorithm>
#include <iterator>
#include <sstream>

/**
 * \file config.cxx
 *
 * \brief Implementation of \link vistk::config configuration\endlink in the pipeline.
 */

namespace vistk
{

config::key_t const config::block_sep = key_t(":");
config::key_t const config::global_value = key_t("_global");

static bool does_not_begin_with(config::key_t const& key, config::key_t const& name);
static config::key_t strip_block_name(config::key_t const& key);

config_t
config
::empty_config(key_t const& name)
{
  return config_t(new config(name, config_t()));
}

config
::~config()
{
}

config_t
config
::subblock(key_t const& key) const
{
  config_t conf = empty_config(key);

  BOOST_FOREACH (key_t const& key_name, available_values())
  {
    if (does_not_begin_with(key_name, key))
    {
      continue;
    }

    key_t const stripped_key_name = strip_block_name(key_name);

    conf->set_value(stripped_key_name, get_value(key_name));
  }

  return conf;
}

config_t
config
::subblock_view(key_t const& key)
{
  return config_t(new config(key, shared_from_this()));
}

void
config
::set_value(key_t const& key, value_t const& value)
{
  if (m_parent)
  {
    m_parent->set_value(m_name + block_sep + key, value);
  }
  else
  {
    if (is_read_only(key))
    {
      value_t const current_value = get_value<value_t>(key, value_t());

      throw set_on_read_only_value_exception(key, current_value, value);
    }

    m_store[key] = value;
  }
}

void
config
::unset_value(key_t const& key)
{
  if (m_parent)
  {
    m_parent->unset_value(m_name + block_sep + key);
  }
  else
  {
    if (is_read_only(key))
    {
      value_t const current_value = get_value<value_t>(key, value_t());

      throw unset_on_read_only_value_exception(key, current_value);
    }

    store_t::iterator const i = m_store.find(key);

    if (i == m_store.end())
    {
      throw no_such_configuration_value_exception(key);
    }

    m_store.erase(i);
  }
}

bool
config
::is_read_only(key_t const& key) const
{
  ro_list_t::iterator i = m_ro_list.find(key);

  return (i != m_ro_list.end());
}

void
config
::mark_read_only(key_t const& key)
{
  m_ro_list.insert(key);
}

void
config
::merge_config(config_t conf)
{
  BOOST_FOREACH (store_t::value_type const& value, conf->m_store)
  {
    key_t const& key = value.first;
    value_t const& val = value.second;

    set_value(key, val);
  }
}

config::keys_t
config
::available_values() const
{
  keys_t keys;

  if (m_parent)
  {
    keys_t parent_keys = m_parent->available_values();

    keys_t::iterator const i = std::remove_if(parent_keys.begin(), parent_keys.end(), boost::bind(does_not_begin_with, _1, m_name));

    parent_keys.erase(i, parent_keys.end());

    std::transform(parent_keys.begin(), parent_keys.end(), std::back_inserter(keys), strip_block_name);
  }
  else
{'fraction_non_alphanumeric': 0.1326766199784516, 'fraction_numerical': 0.005233184546713868, 'mean_word_length': 4.304489795918367, 'pattern_counts': {'":': 2, '<': 22, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3602200', 'n_tokens_mistral': 2479, 'n_tokens_neox': 2414, 'n_words': 503}