Skip to content

Commit

Permalink
Merge branch 'aelzenaar-new_function_call_method'
Browse files Browse the repository at this point in the history
  • Loading branch information
YasserAsmi committed Dec 21, 2015
2 parents 702e130 + 9ea2cb3 commit fcfb1ec
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 11 deletions.
14 changes: 10 additions & 4 deletions CMakeLists.txt
Expand Up @@ -8,10 +8,16 @@ link_directories("lib/")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin/")
set(LIBRARY_OUTPUT_PATH "lib/")

if(CMAKE_COMPILER_IS_GNUCXX)
option(CXX11 "Enable C++11 support" OFF)
message(STATUS "CXX11 = " ${CXX11})

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall -Wextra -Wno-unused-parameter -Wno-variadic-macros -Wno-ignored-qualifiers")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter -Wno-variadic-macros -Wno-ignored-qualifiers")
endif(CMAKE_COMPILER_IS_GNUCXX)
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter -Wno-variadic-macros -Wno-ignored-qualifiers")

if(CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
endif(CXX11)
message(STATUS "CMAKE_CXX_FLAGS = " ${CMAKE_CXX_FLAGS})

add_library(jvar STATIC src/str.cpp src/util.cpp src/arr.cpp src/var.cpp src/json.cpp)

Expand All @@ -36,7 +42,7 @@ target_link_libraries(ex_func jvar -lrt)
add_executable(ex_misc example/misc.cpp)
target_link_libraries(ex_misc jvar -lrt)

install (TARGETS jvar
install (TARGETS jvar
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin)
Expand Down
33 changes: 31 additions & 2 deletions example/func.cpp
Expand Up @@ -3,13 +3,18 @@

#include "jvar.h"

#include <iostream>

using namespace jvar;

/**
* \example func.cpp
* This example shows how to use function objects inside variants. Function objects
* can contain closure/enviroment for the function object and can be called from code
* passing in additional parameters.
*
* Functions can also take as many parameters as wanted at runtime (see \ref ::print()),
* so provide a semi-type-safe way of implementing variadic functions in C++.
*/

// Actual C++ function--it receives env and arg as Variants.
Expand All @@ -34,17 +39,29 @@ Variant makeConverter(Variant tounit, Variant factor, Variant offset = VNULL)
return funcobj;
}

// This function takes as many parameters as you want to give it - it is
// variadic, like printf, but is semi-type-safe.
Variant print(Variant& env, Variant& arg)
{
for (size_t i = 0; i < (size_t)arg.length(); ++i)
{
std::cout << arg[i].toString() << " ";
}
return VEMPTY;
}


int main(int argc, char** argv)
{
Variant res;

// Make function objects
// Make converter function objects

Variant milesToKm = makeConverter("km", 1.60936);
Variant poundsToKg = makeConverter("kg", 0.45460);
Variant farenheitToCelsius = makeConverter("degrees-c", 0.5556, -32l);

// Call function objects and print results
// Call converter function objects and print results

res = milesToKm(10);
printf("milestokm(10) = %s\n", res.toString().c_str());
Expand All @@ -59,4 +76,16 @@ int main(int argc, char** argv)
// milestokm(10) = 16.09 km
// poundsToKg(2.5) = 1.14 kg
// farenheitToCelsius(98l) = 36.67 degrees-c

// C++11 code ONLY
#if __cplusplus > 199711L
Variant printer;
printer.createFunction(print);

// Note the curly braces {} around the arguments.
printer({"test", 2.0, 3, 4, "five", "six"});

// Printed:
// test 2.0 3 4 five six
#endif
}
2 changes: 1 addition & 1 deletion example/jsonparse.cpp
Expand Up @@ -134,7 +134,7 @@ void bench(const char* fn)

jsontxt.readFile(fn, true);

const int count = 100;
const int count = 1;
Variant v;
bool success;

Expand Down
4 changes: 4 additions & 0 deletions example/objs.cpp
Expand Up @@ -86,9 +86,13 @@ void showObjOfArr()
showIter(obj);
}


int main(int argc, char** argv)
{
showSimple();
showAltInit();
showObjOfArr();
showSimple();
showAltInit();
showObjOfArr();
}
24 changes: 20 additions & 4 deletions include/var.h
Expand Up @@ -16,6 +16,10 @@
#define VNULL Variant::sNull
#define VEMPTY Variant::sEmpty

#if __cplusplus > 199711L
#include <initializer_list>
#endif

#define VAR_PATH_DELIM "."

namespace jvar
Expand Down Expand Up @@ -756,9 +760,21 @@ class Variant
* @return Success
*/
bool addEnv(const char* varname, const Variant& value = VEMPTY);
/**
* Executes the function object with no parameters.
*/

#if __cplusplus > 199711L
/**
* Executes the function object with any number of parameters.
*
* This method is called with a brace-enclosed parameter list - see
* \ref func.cpp for an example.
*
* The overloads of operator() taking zero to four parameters call this
* method to do real work and return the result. They can therefore
* be used as shorthand if only four arguments are needed.
*/
Variant operator() (std::initializer_list<const jvar::Variant>&& values);
#endif

Variant operator() ();
Variant operator() (const Variant& value1);
Variant operator() (const Variant& value1, const Variant& value2);
Expand Down Expand Up @@ -1002,7 +1018,7 @@ class Variant
void internalAdd(const Variant& lhs, const Variant& rhs);
void internalSetPtr(const Variant* v);

/** \endcond */
/** \endcond */
};

/** \cond INTERNAL */
Expand Down
58 changes: 58 additions & 0 deletions src/var.cpp
Expand Up @@ -4,6 +4,10 @@
#include "var.h"
#include "json.h"

#if __cplusplus > 199711L
#include <initializer_list>
#endif

namespace jvar
{

Expand Down Expand Up @@ -848,6 +852,59 @@ void Variant::createFunction(Variant (*func)(Variant& env, Variant& arg))
}
}

/*
* Code requires C++11 to work - see below for backwards-compatible code.
*/
#if __cplusplus > 199711L

Variant Variant::operator() (std::initializer_list<const jvar::Variant>&& values)
{
if (mData.type != V_FUNCTION) return VNULL;

Variant arg;

arg.createArray();

for (const auto& value : values)
{
arg.append(value);
}

return mData.funcData->mFunc(mData.funcData->mEnv, arg);
}

Variant Variant::operator() ()
{
return (*this)({});
}

Variant Variant::operator() (const Variant& value1)
{
return (*this)({value1});
}

Variant Variant::operator() (const Variant& value1, const Variant& value2)
{
return (*this)({value1, value2});
}

Variant Variant::operator() (const Variant& value1, const Variant& value2, const Variant& value3)
{
return (*this)({value1, value2, value3});
}


Variant Variant::operator() (const Variant& value1, const Variant& value2, const Variant& value3,
const Variant& value4)
{
return (*this)({value1, value2, value3, value4});
}

/*
* Pre-C++11 code (does not require init lists)
*/
#else

Variant Variant::operator() ()
{
if (mData.type == V_FUNCTION)
Expand Down Expand Up @@ -942,6 +999,7 @@ Variant Variant::operator() (const Variant& value1, const Variant& value2, const
}
return VNULL;
}
#endif

bool Variant::addEnv(const char* varname, const Variant& value /* = VEMPTY */)
{
Expand Down

0 comments on commit fcfb1ec

Please sign in to comment.