Skip to content

Commit

Permalink
add flyweight library (closes #26)
Browse files Browse the repository at this point in the history
  • Loading branch information
eddelbuettel committed May 6, 2016
1 parent a31220c commit 183deac
Show file tree
Hide file tree
Showing 44 changed files with 3,682 additions and 66 deletions.
22 changes: 22 additions & 0 deletions inst/include/boost/flyweight.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* Copyright 2006-2008 Joaquin M Lopez Munoz.
* 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)
*
* See http://www.boost.org/libs/flyweight for library home page.
*/

#ifndef BOOST_FLYWEIGHT_HPP
#define BOOST_FLYWEIGHT_HPP

#if defined(_MSC_VER)
#pragma once
#endif

#include <boost/flyweight/flyweight.hpp>
#include <boost/flyweight/hashed_factory.hpp>
#include <boost/flyweight/refcounted.hpp>
#include <boost/flyweight/simple_locking.hpp>
#include <boost/flyweight/static_holder.hpp>

#endif
116 changes: 116 additions & 0 deletions inst/include/boost/flyweight/assoc_container_factory.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/* Copyright 2006-2015 Joaquin M Lopez Munoz.
* 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)
*
* See http://www.boost.org/libs/flyweight for library home page.
*/

#ifndef BOOST_FLYWEIGHT_ASSOC_CONTAINER_FACTORY_HPP
#define BOOST_FLYWEIGHT_ASSOC_CONTAINER_FACTORY_HPP

#if defined(_MSC_VER)
#pragma once
#endif

#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/flyweight/assoc_container_factory_fwd.hpp>
#include <boost/flyweight/detail/is_placeholder_expr.hpp>
#include <boost/flyweight/detail/nested_xxx_if_not_ph.hpp>
#include <boost/flyweight/factory_tag.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/aux_/lambda_support.hpp>
#include <boost/mpl/if.hpp>

#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#include <utility>
#endif

namespace boost{namespace flyweights{namespace detail{
BOOST_FLYWEIGHT_NESTED_XXX_IF_NOT_PLACEHOLDER_EXPRESSION_DEF(iterator)
BOOST_FLYWEIGHT_NESTED_XXX_IF_NOT_PLACEHOLDER_EXPRESSION_DEF(value_type)
}}} /* namespace boost::flyweights::detail */

/* Factory class using a given associative container.
*/

namespace boost{

namespace flyweights{

template<typename Container>
class assoc_container_factory_class:public factory_marker
{
public:
/* When assoc_container_factory_class<Container> is an MPL placeholder
* expression, referring to Container::iterator and Container::value_type
* force the MPL placeholder expression Container to be instantiated, which
* is wasteful and can fail in concept-checked STL implementations.
* We protect ourselves against this circumstance.
*/

typedef typename detail::nested_iterator_if_not_placeholder_expression<
Container
>::type handle_type;
typedef typename detail::nested_value_type_if_not_placeholder_expression<
Container
>::type entry_type;

handle_type insert(const entry_type& x)
{
return cont.insert(x).first;
}

#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
handle_type insert(entry_type&& x)
{
return cont.insert(std::move(x)).first;
}
#endif

void erase(handle_type h)
{
cont.erase(h);
}

static const entry_type& entry(handle_type h){return *h;}

private:
/* As above, avoid instantiating Container if it is an
* MPL placeholder expression.
*/

typedef typename mpl::if_<
detail::is_placeholder_expression<Container>,
int,
Container
>::type container_type;
container_type cont;

public:
typedef assoc_container_factory_class type;
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,assoc_container_factory_class,(Container))
};

/* assoc_container_factory_class specifier */

template<
typename ContainerSpecifier
BOOST_FLYWEIGHT_NOT_A_PLACEHOLDER_EXPRESSION_DEF
>
struct assoc_container_factory:factory_marker
{
template<typename Entry,typename Key>
struct apply
{
typedef assoc_container_factory_class<
typename mpl::apply2<ContainerSpecifier,Entry,Key>::type
> type;
};
};

} /* namespace flyweights */

} /* namespace boost */

#endif
35 changes: 35 additions & 0 deletions inst/include/boost/flyweight/assoc_container_factory_fwd.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* Copyright 2006-2008 Joaquin M Lopez Munoz.
* 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)
*
* See http://www.boost.org/libs/flyweight for library home page.
*/

#ifndef BOOST_FLYWEIGHT_ASSOC_CONTAINER_FACTORY_FWD_HPP
#define BOOST_FLYWEIGHT_ASSOC_CONTAINER_FACTORY_FWD_HPP

#if defined(_MSC_VER)
#pragma once
#endif

#include <boost/flyweight/detail/not_placeholder_expr.hpp>

namespace boost{

namespace flyweights{

template<typename Container>
class assoc_container_factory_class;

template<
typename ContainerSpecifier
BOOST_FLYWEIGHT_NOT_A_PLACEHOLDER_EXPRESSION
>
struct assoc_container_factory;

} /* namespace flyweights */

} /* namespace boost */

#endif
79 changes: 79 additions & 0 deletions inst/include/boost/flyweight/detail/archive_constructed.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* Copyright 2006-2014 Joaquin M Lopez Munoz.
* 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)
*
* See http://www.boost.org/libs/flyweight for library home page.
*/

#ifndef BOOST_FLYWEIGHT_DETAIL_ARCHIVE_CONSTRUCTED_HPP
#define BOOST_FLYWEIGHT_DETAIL_ARCHIVE_CONSTRUCTED_HPP

#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#pragma once
#endif

#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/noncopyable.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <boost/type_traits/alignment_of.hpp>

namespace boost{

namespace flyweights{

namespace detail{

/* constructs a stack-based object from a serialization archive */

template<typename T>
struct archive_constructed:private noncopyable
{
template<class Archive>
archive_constructed(Archive& ar,const unsigned int version)
{
serialization::load_construct_data_adl(ar,&get(),version);
BOOST_TRY{
ar>>get();
}
BOOST_CATCH(...){
(&get())->~T();
BOOST_RETHROW;
}
BOOST_CATCH_END
}

template<class Archive>
archive_constructed(const char* name,Archive& ar,const unsigned int version)
{
serialization::load_construct_data_adl(ar,&get(),version);
BOOST_TRY{
ar>>serialization::make_nvp(name,get());
}
BOOST_CATCH(...){
(&get())->~T();
BOOST_RETHROW;
}
BOOST_CATCH_END
}

~archive_constructed()
{
(&get())->~T();
}

T& get(){return *static_cast<T*>(static_cast<void*>(&space));}

private:
typename aligned_storage<sizeof(T),alignment_of<T>::value>::type space;
};

} /* namespace flyweights::detail */

} /* namespace flyweights */

} /* namespace boost */

#endif
85 changes: 85 additions & 0 deletions inst/include/boost/flyweight/detail/default_value_policy.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/* Copyright 2006-2014 Joaquin M Lopez Munoz.
* 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)
*
* See http://www.boost.org/libs/flyweight for library home page.
*/

#ifndef BOOST_FLYWEIGHT_DETAIL_DEFAULT_VALUE_POLICY_HPP
#define BOOST_FLYWEIGHT_DETAIL_DEFAULT_VALUE_POLICY_HPP

#if defined(_MSC_VER)
#pragma once
#endif

#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/detail/workaround.hpp>
#include <boost/flyweight/detail/perfect_fwd.hpp>
#include <boost/flyweight/detail/value_tag.hpp>

/* Default value policy: the key is the same as the value.
*/

namespace boost{

namespace flyweights{

namespace detail{

template<typename Value>
struct default_value_policy:value_marker
{
typedef Value key_type;
typedef Value value_type;

struct rep_type
{
/* template ctors */

#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)&&\
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)&&\
BOOST_WORKAROUND(__GNUC__,<=4)&&(__GNUC__<4||__GNUC_MINOR__<=4)

/* GCC 4.4.2 (and probably prior) bug: the default ctor generated by the
* variadic temmplate ctor below fails to value-initialize x.
*/

rep_type():x(){}
#endif

#define BOOST_FLYWEIGHT_PERFECT_FWD_CTR_BODY(args) \
:x(BOOST_FLYWEIGHT_FORWARD(args)){}

BOOST_FLYWEIGHT_PERFECT_FWD(
explicit rep_type,
BOOST_FLYWEIGHT_PERFECT_FWD_CTR_BODY)

#undef BOOST_FLYWEIGHT_PERFECT_FWD_CTR_BODY

rep_type(const rep_type& r):x(r.x){}

#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
rep_type(rep_type&& r):x(std::move(r.x)){}
#endif

operator const value_type&()const{return x;}

value_type x;
};

static void construct_value(const rep_type&){}
static void copy_value(const rep_type&){}

#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
static void move_value(const rep_type&){}
#endif
};

} /* namespace flyweights::detail */

} /* namespace flyweights */

} /* namespace boost */

#endif
Loading

0 comments on commit 183deac

Please sign in to comment.