diff --git a/cmake/AkantuMacros.cmake b/cmake/AkantuMacros.cmake index ecdfd8127..e367913c8 100644 --- a/cmake/AkantuMacros.cmake +++ b/cmake/AkantuMacros.cmake @@ -1,160 +1,160 @@ #=============================================================================== # @file AkantuMacros.cmake # # @author Guillaume Anciaux <guillaume.anciaux@epfl.ch> # @author Nicolas Richart <nicolas.richart@epfl.ch> # # @date Thu Feb 17 17:28:21 2011 # # @brief Set of macros used by akantu cmake files # # @section LICENSE # # Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) # Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see <http://www.gnu.org/licenses/>. # #=============================================================================== macro(check_for_isnan result) include(CheckFunctionExists) check_function_exists(std::isnan HAVE_STD_ISNAN) if(HAVE_STD_ISNAN) set(result "std::isnan(x)") else() check_function_exists(isnan HAVE_ISNAN) if(HAVE_ISNAN) set(result "(::isnan(x))") else() check_function_exists(_isnan HAVE_ISNAN_MATH_H) if(HAVE_ISNAN_MATH_H) set(result "(_isnan(x))") else() set(result (x == std::numeric_limits<Real>::quiet_NAN())) endif() endif() endif() endmacro() #=============================================================================== macro(copy_files target_depend) foreach(_file ${ARGN}) set(_target ${CMAKE_CURRENT_BINARY_DIR}/${_file}) set(_source ${CMAKE_CURRENT_SOURCE_DIR}/${_file}) add_custom_command( OUTPUT ${_target} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${_source} ${_target} DEPENDS ${_source} ) set(_target_name ${target_depend}_${_file}) add_custom_target(${_target_name} DEPENDS ${_target}) add_dependencies(${target_depend} ${_target_name}) endforeach() endmacro() #=============================================================================== macro(add_akantu_definitions) foreach(_definition ${AKANTU_DEFINITIONS}) add_definitions(-D${_definition}) endforeach() endmacro() macro(include_boost) find_package(Boost REQUIRED) mark_as_advanced(Boost_DIR) if(Boost_FOUND) - list(APPEND AKANTU_EXTERNAL_LIB_INCLUDE_DIR ${Boost_INCLUDE_DIRS}) + list(APPEND AKANTU_EXTERNAL_LIB_INCLUDE_DIR ${Boost_INCLUDE_DIRS} ${Boost_INCLUDE_DIR}) endif() message(STATUS "Looking for Boost liraries") set(AKANTU_BOOST_COMPONENT_ALREADY_DONE) foreach(_comp ${AKANTU_BOOST_COMPONENTS}) list(FIND AKANTU_BOOST_COMPONENT_ALREADY_DONE ${_comp} _res) if(_res EQUAL -1) find_package(Boost COMPONENTS ${_comp} QUIET) string(TOUPPER ${_comp} _u_comp) if(Boost_${_u_comp}_FOUND) message(STATUS " ${_comp}: FOUND") set(AKANTU_BOOST_${_u_comp} TRUE CACHE INTERNAL "" FORCE) list(APPEND AKANTU_EXTERNAL_LIBRARIES ${Boost_${_u_comp}_LIBRARY}) else() message(STATUS " ${_comp}: NOT FOUND") endif() list(APPEND AKANTU_BOOST_COMPONENT_ALREADY_DONE ${_comp}) endif() endforeach() endmacro() #=============================================================================== if(__CMAKE_PARSE_ARGUMENTS_INCLUDED) return() endif() set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE) function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames) # first set all result variables to empty/FALSE foreach(arg_name ${_singleArgNames} ${_multiArgNames}) set(${prefix}_${arg_name}) endforeach(arg_name) foreach(option ${_optionNames}) set(${prefix}_${option} FALSE) endforeach(option) set(${prefix}_UNPARSED_ARGUMENTS) set(insideValues FALSE) set(currentArgName) # now iterate over all arguments and fill the result variables foreach(currentArg ${ARGN}) list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1) if(insideValues) if("${insideValues}" STREQUAL "SINGLE") set(${prefix}_${currentArgName} ${currentArg}) set(insideValues FALSE) elseif("${insideValues}" STREQUAL "MULTI") list(APPEND ${prefix}_${currentArgName} ${currentArg}) endif() else(insideValues) list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg}) endif(insideValues) else() if(NOT ${optionIndex} EQUAL -1) set(${prefix}_${currentArg} TRUE) set(insideValues FALSE) elseif(NOT ${singleArgIndex} EQUAL -1) set(currentArgName ${currentArg}) set(${prefix}_${currentArgName}) set(insideValues "SINGLE") elseif(NOT ${multiArgIndex} EQUAL -1) set(currentArgName ${currentArg}) set(${prefix}_${currentArgName}) set(insideValues "MULTI") endif() endif() endforeach(currentArg) # propagate the result variables to the caller: foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames}) set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE) endforeach(arg_name) set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE) endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 752a64a5e..b3b41239f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,150 +1,153 @@ #=============================================================================== # @file CMakeLists.txt # # @author Guillaume Anciaux <guillaume.anciaux@epfl.ch> # @author Nicolas Richart <nicolas.richart@epfl.ch> # # @date Mon Nov 28 16:54:12 2011 # # @brief CMake file for the library # # @section LICENSE # # Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) # Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see <http://www.gnu.org/licenses/>. # #=============================================================================== #=============================================================================== # Package Management #=============================================================================== generate_source_list_from_packages(${CMAKE_CURRENT_BINARY_DIR} AKANTU_LIBRARY_SRCS AKANTU_LIBRARY_INLINE_HDRS AKANTU_LIBRARY_HDRS AKANTU_LIBRARY_INCLUDE_DIRS) #=========================================================================== # header for blas/lapack (any other fortran libraries) #=========================================================================== if(AKANTU_LAPACK OR AKANTU_BLAS) include(FortranCInterface) FortranCInterface_HEADER( ${CMAKE_CURRENT_BINARY_DIR}/aka_fortran_mangling.hh MACRO_NAMESPACE "AKA_FC_") mark_as_advanced(CDEFS) endif() configure_file(common/aka_config.hh.in "${CMAKE_CURRENT_BINARY_DIR}/aka_config.hh" @ONLY) list(APPEND AKANTU_LIBRARY_HDRS ${CMAKE_CURRENT_BINARY_DIR}/aka_config.hh) #=========================================================================== # header precompilation #=========================================================================== set(AKANTU_COMMON_HDR_TO_PRECOMPILE common/aka_vector.hh common/aka_math.hh common/aka_types.hh fem/element_class.hh ) set(AKANTU_PRECOMPILE_HDR_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/common/ ${CMAKE_CURRENT_BINARY_DIR}/fem/ ) set(AKANTU_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR} ${AKANTU_LIBRARY_INCLUDE_DIRS} ${AKANTU_PRECOMPILE_HDR_INCLUDE_DIRS} CACHE INTERNAL "Internal include directories to link with Akantu as a subproject") include_directories(${AKANTU_INCLUDE_DIRS} ${AKANTU_EXTERNAL_LIB_INCLUDE_DIR}) function(generate_material_list) message(STATUS "Determining the list of recognized materials...") + + set(_include_dirs ${AKANTU_INCLUDE_DIRS} ${AKANTU_EXTERNAL_LIB_INCLUDE_DIR}) + try_run(_material_list_run _material_list_compile ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/material_lister.cc - CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${AKANTU_INCLUDE_DIRS}" + CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${_include_dirs}" COMPILE_DEFINITIONS "-DAKANTU_CMAKE_LIST_MATERIALS" COMPILE_OUTPUT_VARIABLE _compile_results RUN_OUTPUT_VARIABLE _result_material_list) if(_material_list_compile AND "${_material_list_run}" EQUAL 0) message(STATUS "Materials included in Akantu:") string(REPLACE "\n" ";" _material_list "${_result_material_list}") foreach(_mat ${_material_list}) string(REPLACE ":" ";" _mat_key "${_mat}") list(GET _mat_key 0 _key) list(GET _mat_key 1 _class) list(LENGTH _mat_key _l) if("${_l}" GREATER 2) list(REMOVE_AT _mat_key 0 1) set(_opt " -- options: [") foreach(_o ${_mat_key}) set(_opt "${_opt} ${_o}") endforeach() set(_opt "${_opt} ]") else() set(_opt "") endif() message(STATUS " ${_class} -- key: ${_key}${_opt}") endforeach() else() message(STATUS "Could not determine the list of materials.") message("${_compile_results}") endif() endfunction() generate_material_list() if(CMAKE_COMPILER_IS_GNUCXX) include(PCHgcc) foreach(_header ${AKANTU_COMMON_HDR_TO_PRECOMPILE}) add_pch_rule(${_header} AKANTU_LIBRARY_SRCS) endforeach() elseif(CMAKE_COMPILER_IS_GNUCXX) endif() #=============================================================================== # Library generation #=============================================================================== add_library(akantu ${AKANTU_LIBRARY_SRCS}) target_link_libraries(akantu ${AKANTU_EXTERNAL_LIBRARIES}) list(APPEND AKANTU_PUBLIC_HDRS ${AKANTU_LIBRARY_HDRS} ${AKANTU_LIBRARY_INLINE_HDRS}) set_target_properties(akantu PROPERTIES ${AKANTU_LIBRARY_PROPERTIES}) set_target_properties(akantu PROPERTIES PUBLIC_HEADER "${AKANTU_PUBLIC_HDRS}") list(APPEND AKANTU_EXPORT_LIST akantu) install(TARGETS akantu EXPORT ${AKANTU_TARGETS_EXPORT} LIBRARY DESTINATION lib COMPONENT lib ARCHIVE DESTINATION lib COMPONENT lib PUBLIC_HEADER DESTINATION include/akantu/ COMPONENT dev ) if("${AKANTU_TARGETS_EXPORT}" STREQUAL "AkantuLibraryDepends") install(EXPORT AkantuLibraryDepends DESTINATION lib/akantu COMPONENT dev) endif() #Export for build tree export(TARGETS ${AKANTU_EXPORT_LIST} FILE "${CMAKE_BINARY_DIR}/AkantuLibraryDepends.cmake") export(PACKAGE Akantu) diff --git a/src/io/parser/cppargparse/cppargparse.hh b/src/io/parser/cppargparse/cppargparse.hh index 00e3bfabe..8a7d3da69 100644 --- a/src/io/parser/cppargparse/cppargparse.hh +++ b/src/io/parser/cppargparse/cppargparse.hh @@ -1,169 +1,169 @@ /** * @file cppargparse.hh * * @author Nicolas Richart <nicolas.richart@epfl.ch> * * @date Fri Mar 28 14:07:02 2014 * * @brief Get the commandline options and store them as short, long and others * * @section LICENSE * * Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ #include <map> #include <string> #include <iostream> #include <vector> #ifndef __CPPARGPARSE_HH__ #define __CPPARGPARSE_HH__ namespace cppargparse { enum ArgumentType { _string, _integer, _float, _boolean }; enum ArgumentNargs { _one_if_possible = -1, _at_least_one = -2, _any = -3 }; enum ParseFlags { _no_flags = 0x0, _stop_on_not_parsed = 0x1, _remove_parsed = 0x2 }; inline ParseFlags operator|(const ParseFlags & a, const ParseFlags & b) { ParseFlags tmp = ParseFlags(int(a) | int(b)); return tmp; } class ArgumentParser { public: class Argument { public: Argument() : name(std::string()) {} virtual ~Argument() {} virtual void printself(std::ostream & stream) const = 0; template<class T> operator T() const; std::string name; }; /// constructor ArgumentParser(); /// destroy everything ~ArgumentParser(); /// add an argument with a description void addArgument(const std::string & name_or_flag, const std::string & help, int nargs = 1, ArgumentType type = _string); /// add an argument with an help and a default value template<class T> void addArgument(const std::string & name_or_flag, const std::string & help, int nargs, ArgumentType type, T def); /// add an argument with an help and a default + const value template<class T> void addArgument(const std::string & name_or_flag, const std::string & help, int nargs, ArgumentType type, T def, T cons); /// parse argc, argv void parse(int & argc, char ** & argv, int flags = _stop_on_not_parsed); /// print the content in the stream void printself(std::ostream & stream) const; /// print the help text void print_help(std::ostream & stream = std::cout) const; /// print the usage text void print_usage(std::ostream & stream = std::cout) const; /// set an external function to replace the exit function from the stdlib void setExternalExitFunction(void (*external_exit)(int)) { this->external_exit = external_exit; } /// accessor for a registered argument that was parsed, throw an exception if /// the argument does not exist or was not set (parsed or default value) const Argument & operator[](const std::string & name) const; -private: +public: class _Argument; template<class T> class ArgumentStorage; - +private: _Argument & _addArgument(const std::string & name_or_flag, const std::string & description, int nargs, ArgumentType type); void _exit(const std::string & msg = "", int status = 0); bool checkType(ArgumentType type, const std::string & value) const; void print_usage_nargs(std::ostream & stream, const _Argument & argument) const; void print_help_argument(std::ostream & stream, const _Argument & argument) const; private: typedef std::map<std::string, _Argument *> _Arguments; typedef std::map<std::string, Argument *> Arguments; typedef std::map<std::string, _Argument *> ArgumentKeyMap; typedef std::vector<_Argument *> PositionalArgument; _Arguments arguments; ArgumentKeyMap key_args; PositionalArgument pos_args; Arguments success_parsed; std::string program_name; void (*external_exit)(int); }; } inline std::ostream & operator<<(std::ostream & stream, const cppargparse::ArgumentParser & argparse) { argparse.printself(stream); return stream; } #endif /* __CPPARGPARSE_HH__ */ #include "cppargparse_tmpl.hh" diff --git a/src/io/parser/cppargparse/cppargparse_tmpl.hh b/src/io/parser/cppargparse/cppargparse_tmpl.hh index 9fbe094d6..d9bb0087f 100644 --- a/src/io/parser/cppargparse/cppargparse_tmpl.hh +++ b/src/io/parser/cppargparse/cppargparse_tmpl.hh @@ -1,214 +1,214 @@ /** * @file cppargparse_tmpl.hh * * @author Nicolas Richart <nicolas.richart@epfl.ch> * * @date Mon Mar 31 21:15:31 2014 * * @brief * * @section LICENSE * * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see <http://www.gnu.org/licenses/>. * */ /* -------------------------------------------------------------------------- */ #include <stdexcept> #ifndef __CPPARGPARSE_TMPL_HH__ #define __CPPARGPARSE_TMPL_HH__ namespace cppargparse { /* -------------------------------------------------------------------------- */ /* Argument */ /* -------------------------------------------------------------------------- */ struct ArgumentParser::_Argument : public Argument { _Argument() : Argument(), help(std::string()), nargs(1), type(_string), required(false), parsed(false), has_default(false), has_const(false), is_positional(false) {} virtual ~_Argument() {} void setValues(std::vector<std::string> & values) { for (std::vector<std::string>::iterator it = values.begin(); it != values.end(); ++it) { this->addValue(*it); } } virtual void addValue(std::string & value) = 0; virtual void setToDefault() = 0; virtual void setToConst() = 0; std::ostream & printDefault(std::ostream & stream) const { stream << std::boolalpha; if(has_default) { stream << " (default: "; this->_printDefault(stream); stream << ")"; } if(has_const) { stream << " (const: "; this->_printConst(stream); stream << ")"; } return stream; } virtual std::ostream & _printDefault(std::ostream & stream) const = 0; virtual std::ostream & _printConst(std::ostream & stream) const = 0; std::string help; int nargs; ArgumentType type; bool required; bool parsed; bool has_default; bool has_const; std::vector<std::string> keys; bool is_positional; }; /* -------------------------------------------------------------------------- */ template<class T> class ArgumentParser::ArgumentStorage : public ArgumentParser::_Argument { public: ArgumentStorage() : _default(T()), _const(T()), values(std::vector<T>()) {} virtual void addValue(std::string & value) { std::stringstream sstr(value); T t; sstr >> t; values.push_back(t); } virtual void setToDefault() { values.clear(); values.push_back(_default); } virtual void setToConst() { values.clear(); values.push_back(_const); } void printself(std::ostream & stream) const { stream << this->name << " ="; stream << std::boolalpha; // for boolean for(typename std::vector<T>::const_iterator vit = this->values.begin(); vit != this->values.end(); ++vit) { stream << " " << *vit; } } virtual std::ostream & _printDefault(std::ostream & stream) const { stream << _default; return stream; } virtual std::ostream & _printConst(std::ostream & stream) const { stream << _const; return stream; } T _default; T _const; std::vector<T> values; }; /* -------------------------------------------------------------------------- */ template<> inline void ArgumentParser::ArgumentStorage<std::string>::addValue(std::string & value) { values.push_back(value); } template<class T> struct is_vector { enum { value = false }; }; template<class T> struct is_vector< std::vector<T> > { enum { value = true }; }; - + /* -------------------------------------------------------------------------- */ -template<class T, bool is_vector = is_vector<T>::value> +template<class T, bool is_vector = cppargparse::is_vector<T>::value> struct cast_helper { static T cast(const ArgumentParser::Argument & arg) { const ArgumentParser::ArgumentStorage<T> & _arg = dynamic_cast<const ArgumentParser::ArgumentStorage<T> &>(arg); if(_arg.values.size() == 1) { return _arg.values[0]; } else { throw std::length_error("Not enougth or too many argument where passed for the command line argument: " + arg.name); } } }; template<class T> struct cast_helper<T, true> { static T cast(const ArgumentParser::Argument & arg) { const ArgumentParser::ArgumentStorage<T> & _arg = dynamic_cast<const ArgumentParser::ArgumentStorage<T> &>(arg); return _arg.values; } }; /* -------------------------------------------------------------------------- */ template<class T> ArgumentParser::Argument::operator T() const{ return cast_helper<T>::cast(*this); } template<class T> void ArgumentParser::addArgument(const std::string & name_or_flag, const std::string & help, int nargs, ArgumentType type, T def) { _Argument & arg = _addArgument(name_or_flag, help, nargs, type); dynamic_cast<ArgumentStorage<T> &>(arg)._default = def; arg.has_default = true; } template<class T> void ArgumentParser::addArgument(const std::string & name_or_flag, const std::string & help, int nargs, ArgumentType type, T def, T cons) { _Argument & arg = _addArgument(name_or_flag, help, nargs, type); dynamic_cast<ArgumentStorage<T> &>(arg)._default = def; arg.has_default = true; dynamic_cast<ArgumentStorage<T> &>(arg)._const = cons; arg.has_const = true; } } #endif /* __AKANTU_CPPARGPARSE_TMPL_HH__ */