Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost::mpl: How to generate pre-generated header files for lists with more than 50 entries?

I want to code a state machine which has a reaction list with more than 50 entries.

I found here some python scripts to generate header files for lists with more than 50 entries.

But I cannot manage to generate a single header file. Can someone please explain to me how to use theses scripts? I also didn't find any help in boost documention.

Any help would be appreciated.

like image 245
Klaus Kempf Avatar asked Nov 19 '25 06:11

Klaus Kempf


1 Answers

Important Update:

A more improved script, which only requires a working python environment is described in this answer to this question.

Original Answer

See my answer to your question on the Boost mailing-list.

The following bash-code will generate the MPL-containers for 51 to 100 entries. If you do not care about the other MPL-container types and just want to generate MPL-lists, adjust the value of CONTAINERS accordingly.

#! /bin/bash

# The name of this script.
SCRIPT_NAME=$(basename $0)
# The usage message for this script.
USAGE="Usage:  ${SCRIPT_NAME} <path-to-boost-source> [<new-value-for BOOST_MPL_LIMIT_VECTOR_SIZE>]"

# Script-arguments:
# The (absolute) path to the directory containing the Boost-source.
SOURCE=$(readlink -e "$1")
# The new limit for Boost.MPL's vector.
NEW_BOOST_MPL_LIMIT_VECTOR_SIZE=$2

# Check validity of arguments.
if [[ -z "${SOURCE}" ]] || ! [[ -d "${SOURCE}" ]]; then
  echo "Missing path to Boost directory."
  echo ${USAGE}
  exit
fi
REGEX_INTEGER='^[0-9]+$'
if [[ -n "${NEW_BOOST_MPL_LIMIT_VECTOR_SIZE}" ]] && ! [[ ${NEW_BOOST_MPL_LIMIT_VECTOR_SIZE} =~ ${REGEX_INTEGER} ]]; then
  echo "New size for BOOST_MPL_LIMIT_VECTOR_SIZE must be an unsigned integer!"
  echo ${USAGE}
  exit
fi


# The Boost.MPL-containers for which more preprocessed
# header-files shall be generated.
CONTAINERS="vector list set map"
# The same containers without Boost.MPL-map.
CONTAINERS_WITHOUT_MAP=$(echo ${CONTAINERS} | sed 's/map//g')

# Change into include-directory of Boost.MPL.
pushd ${SOURCE}/boost/mpl  >/dev/null 2>&1

# Possibly change the limit for Boost.MPL's vector.
if [[ -n "${NEW_BOOST_MPL_LIMIT_VECTOR_SIZE}" ]]; then
  sed -i "s/\(define\s\+BOOST_MPL_LIMIT_VECTOR_SIZE\s\+\)[0-9]\+/\1${NEW_BOOST_MPL_LIMIT_VECTOR_SIZE}/" ./limits/vector.hpp
fi

# Create hpp-files for each MPL-container with 60 to 100 elements
# which will be used during generation.
for container in ${CONTAINERS}; do
  for i in {6..10}; do
    sed -e "s/50/${i}0/g" \
        -e "s/41/$((i-1))1/g" \
        -e "s/40/$((i-1))0/g" \
        ./${container}/${container}50.hpp \
      > ./${container}/${container}${i}0.hpp;
  done
done
for container in ${CONTAINERS_WITHOUT_MAP}; do
  for i in {6..10}; do
    sed -e "s/50/${i}0/g" \
        -e "s/41/$((i-1))1/g" \
        -e "s/40/$((i-1))0/g" \
        ./${container}/${container}50_c.hpp \
      > ./${container}/${container}${i}0_c.hpp;
  done
done

# Leave include-directory of Boost.MPL.
popd  >/dev/null 2>&1
# Change into source-directory of Boost.MPL.
pushd ${SOURCE}/libs/mpl/preprocessed  >/dev/null 2>&1

# Create cpp-files for each MPL-container with 60 to 100 elements
# which will be used during generation.
for container in ${CONTAINERS}; do
  for i in {6..10}; do
    sed -e "s/50/${i}0/g" \
        -e "s/41/$((i-1))1/g" \
        -e "s/40/$((i-1))0/g" \
        ./${container}/${container}50.cpp \
      > ./${container}/${container}${i}0.cpp;
  done
done
for container in ${CONTAINERS_WITHOUT_MAP}; do
  for i in {6..10}; do
    sed -e "s/50/${i}0/g" \
        -e "s/41/$((i-1))1/g" \
        -e "s/40/$((i-1))0/g" \
        ./${container}/${container}50_c.cpp \
      > ./${container}/${container}${i}0_c.cpp;
  done
done

# Now generate MPL-preprocessed files using the python-scripts.
python preprocess_vector.py all ${SOURCE}
python preprocess_list.py   all ${SOURCE}
python preprocess_set.py    all ${SOURCE}
python preprocess_map.py    all ${SOURCE}
python preprocess.py        all ${SOURCE}

# Leave source-directory of Boost.MPL.
popd  >/dev/null 2>&1

For even bigger containers with more than 100 entries, adjust the range in the for-loops.

I hope that helps.
Deniz

Update:

I realized that my original version of the script did only generate the numbered versions of the MPL-container headers. However, it did not update the non-numbered versions.

I fixed it by adding python preprocess.py all ${SOURCE} near the end of the script. However, this does only generate modified versions of the non-numbered MPL-container headers if during generation the corresponding macro settings (e.g. a higher value for BOOST_MPL_LIMIT_VECTOR_SIZE) are different than the original values.

These modifications can be made in the file user.hpp within each subdirectory of ${SOURCE}/libs/mpl/preprocessed/include.

For example, by adding

#define BOOST_MPL_LIMIT_VECTOR_SIZE 30

to ${SOURCE}/libs/mpl/preprocessed/include/gcc/user.hpp the boost::mpl::vector (included from boost/mpl/vector.hpp) is able to hold 30 elements, now, instead of the default 20.

Note:

However, it might not be a good idea to adjust values like BOOST_MPL_LIMIT_VECTOR_SIZE only for generation and leave its value defined in ${SOURCE}/boost/mpl/limits/vector.hpp untouched.
Possibly, this does not even compile because the underlying boost::mpl::vector21 to boost::mpl::vectorN cannot be found (because not being included automatically). Best solution is probably to adjust the value in ${SOURCE}/boost/mpl/limits/vector.hpp. The above bash-script can automatically do so, if the second (optional) argument is given.

like image 100
Deniz Bahadir Avatar answered Nov 20 '25 19:11

Deniz Bahadir



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!