PPL Configured Java Language Interface  0.12.1
ppl_java_common.inlines.hh
Go to the documentation of this file.
00001 /* Domain-independent part of the Java interface: inline functions.
00002    Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
00003    Copyright (C) 2010-2012 BUGSENG srl (http://bugseng.com)
00004 
00005 This file is part of the Parma Polyhedra Library (PPL).
00006 
00007 The PPL is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 The PPL is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with this program; if not, write to the Free Software Foundation,
00019 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
00020 
00021 For the most up-to-date information see the Parma Polyhedra Library
00022 site: http://bugseng.com/products/ppl/ . */
00023 
00024 #ifndef PPL_ppl_java_common_inlines_hh
00025 #define PPL_ppl_java_common_inlines_hh 1
00026 
00027 #include <cassert>
00028 
00029 namespace Parma_Polyhedra_Library {
00030 
00031 namespace Interfaces {
00032 
00033 namespace Java {
00034 
00035 template <typename U, typename V>
00036 U
00037 jtype_to_unsigned(const V& value) {
00038   if (value < 0)
00039     throw std::invalid_argument("not an unsigned integer.");
00040 
00041   if (sizeof(U) < sizeof(V)) {
00042     if (value > static_cast<V>(std::numeric_limits<U>::max()))
00043       throw std::invalid_argument("unsigned integer out of range.");
00044   }
00045 
00046   return value;
00047 }
00048 
00049 template <typename T>
00050 inline void
00051 set_ptr(JNIEnv* env, jobject ppl_object,
00052         const T* address, bool to_be_marked) {
00053   const T* ptr = (to_be_marked ? mark(address) : address);
00054   jlong pointer_value = reinterpret_cast<jlong>(ptr);
00055   assert(reinterpret_cast<const T*>(pointer_value) == ptr);
00056   env->SetLongField(ppl_object, cached_FMIDs.PPL_Object_ptr_ID, pointer_value);
00057 }
00058 
00059 inline void*
00060 get_ptr(JNIEnv* env, jobject ppl_object) {
00061   jlong pointer_value
00062     = env->GetLongField(ppl_object, cached_FMIDs.PPL_Object_ptr_ID);
00063   void* ptr = reinterpret_cast<void*>(pointer_value);
00064   assert(reinterpret_cast<jlong>(ptr) == pointer_value);
00065   return unmark(ptr);
00066 }
00067 
00068 inline bool
00069 is_java_marked(JNIEnv* env, jobject ppl_object) {
00070   jlong pointer_value
00071     = env->GetLongField(ppl_object, cached_FMIDs.PPL_Object_ptr_ID);
00072   const void* ptr = reinterpret_cast<const void*>(pointer_value);
00073   assert(reinterpret_cast<jlong>(ptr) == pointer_value);
00074   return marked(ptr);
00075 }
00076 
00077 inline void
00078 set_coefficient(JNIEnv* env, jobject dst, jobject src) {
00079   jobject src_bi
00080     = env->GetObjectField(src, cached_FMIDs.Coefficient_value_ID);
00081   env->SetObjectField(dst, cached_FMIDs.Coefficient_value_ID, src_bi);
00082 }
00083 
00084 inline void
00085 set_by_reference(JNIEnv* env, jobject by_ref_dst, jobject src) {
00086   env->SetObjectField(by_ref_dst,
00087                       cached_FMIDs.By_Reference_obj_ID,
00088                       src);
00089 }
00090 
00091 inline jobject
00092 get_by_reference(JNIEnv* env, jobject by_reference) {
00093   return env->GetObjectField(by_reference, cached_FMIDs.By_Reference_obj_ID);
00094 }
00095 
00096 template <typename R>
00097 jobject
00098 build_linear_expression(JNIEnv* env, const R& r) {
00099   jobject j_ret;
00100   PPL_DIRTY_TEMP_COEFFICIENT(coefficient);
00101   dimension_type varid = 0;
00102   dimension_type space_dimension = r.space_dimension();
00103   while (varid < space_dimension
00104          && (coefficient = r.coefficient(Variable(varid))) == 0)
00105     ++varid;
00106   if (varid >= space_dimension) {
00107     jobject j_coefficient_zero = build_java_coeff(env, Coefficient(0));
00108     j_ret = env->NewObject(cached_classes.Linear_Expression_Coefficient,
00109                            cached_FMIDs.Linear_Expression_Coefficient_init_ID,
00110                            j_coefficient_zero);
00111     CHECK_RESULT_THROW(env, j_ret);
00112   }
00113   else {
00114     jmethodID coeff_var_init_ID
00115       = cached_FMIDs.Linear_Expression_Times_init_from_coeff_var_ID;
00116     jobject j_coefficient = build_java_coeff(env, coefficient);
00117     jobject j_variable = build_java_variable(env, Variable(varid));
00118     jclass j_le_times_class = cached_classes.Linear_Expression_Times;
00119     jobject j_coeff_var = env->NewObject(j_le_times_class,
00120                                          coeff_var_init_ID,
00121                                          j_coefficient, j_variable);
00122     CHECK_EXCEPTION_THROW(env);
00123     j_ret = j_coeff_var;
00124     while (true) {
00125       ++varid;
00126       while (varid < space_dimension
00127              && (coefficient = r.coefficient(Variable(varid))) == 0)
00128         ++varid;
00129       if (varid >= space_dimension)
00130         break;
00131       else {
00132         j_coefficient = build_java_coeff(env, coefficient);
00133         j_variable = build_java_variable(env, Variable(varid));
00134         j_coeff_var = env->NewObject(j_le_times_class,
00135                                      coeff_var_init_ID,
00136                                      j_coefficient, j_variable);
00137         CHECK_EXCEPTION_THROW(env);
00138         j_ret = env->CallObjectMethod(j_ret,
00139                                       cached_FMIDs.Linear_Expression_sum_ID,
00140                                       j_coeff_var);
00141         CHECK_EXCEPTION_THROW(env);
00142       }
00143     }
00144   }
00145   return j_ret;
00146 }
00147 
00148 inline Variable
00149 build_cxx_variable(JNIEnv* env, jobject j_var) {
00150   return Variable(env->GetIntField(j_var, cached_FMIDs.Variable_varid_ID));
00151 }
00152 
00153 inline jobject
00154 build_java_variable(JNIEnv* env, const Variable var) {
00155   jobject ret = env->NewObject(cached_classes.Variable,
00156                                cached_FMIDs.Variable_init_ID,
00157                                var.id());
00158   CHECK_RESULT_THROW(env, ret);
00159   return ret;
00160 }
00161 
00162 inline Coefficient
00163 build_cxx_coeff(JNIEnv* env, jobject j_coeff) {
00164   jstring bi_string
00165     = (jstring) env->CallObjectMethod(j_coeff,
00166                                       cached_FMIDs.Coefficient_toString_ID);
00167   CHECK_EXCEPTION_THROW(env);
00168   const char *nativeString = env->GetStringUTFChars(bi_string, 0);
00169   CHECK_RESULT_THROW(env, nativeString);
00170   PPL_DIRTY_TEMP_COEFFICIENT(ppl_coeff);
00171   ppl_coeff = Coefficient(nativeString);
00172   env->ReleaseStringUTFChars(bi_string, nativeString);
00173   return ppl_coeff;
00174 }
00175 
00176 inline jobject
00177 build_java_coeff(JNIEnv* env, const Coefficient& ppl_coeff) {
00178   std::ostringstream s;
00179   s << ppl_coeff;
00180   std::string str = s.str();
00181   jstring coeff_string = env->NewStringUTF(str.c_str());
00182   CHECK_RESULT_THROW(env, coeff_string);
00183   jobject ret = env->NewObject(cached_classes.Coefficient,
00184                                cached_FMIDs.Coefficient_init_from_String_ID,
00185                                coeff_string);
00186   CHECK_RESULT_THROW(env, ret);
00187   return ret;
00188 }
00189 
00190 template <typename System, typename Elem_Builder>
00191 System
00192 build_cxx_system(JNIEnv* env, jobject j_iterable, Elem_Builder build_cxx_elem) {
00193   // Get the iterator.
00194   jobject j_iter
00195     = env->CallObjectMethod(j_iterable, cached_FMIDs.System_iterator_ID);
00196   CHECK_EXCEPTION_THROW(env);
00197   // Get the iterator method IDs.
00198   jmethodID has_next_mID = cached_FMIDs.System_Iterator_has_next_ID;
00199   jmethodID next_mID = cached_FMIDs.System_Iterator_next_ID;
00200   // Initialize an empty system.
00201   System cxx_sys;
00202   jobject j_element;
00203   jboolean has_next_value = env->CallBooleanMethod(j_iter, has_next_mID);
00204   CHECK_EXCEPTION_ASSERT(env);
00205   while (has_next_value) {
00206     j_element = env->CallObjectMethod(j_iter, next_mID);
00207     CHECK_EXCEPTION_ASSERT(env);
00208     cxx_sys.insert(build_cxx_elem(env, j_element));
00209     has_next_value = env->CallBooleanMethod(j_iter, has_next_mID);
00210     CHECK_EXCEPTION_ASSERT(env);
00211   }
00212   return cxx_sys;
00213 }
00214 
00215 inline Congruence_System
00216 build_cxx_congruence_system(JNIEnv* env, jobject j_iterable) {
00217   return
00218     build_cxx_system<Congruence_System>(env, j_iterable, build_cxx_congruence);
00219 }
00220 
00221 inline Constraint_System
00222 build_cxx_constraint_system(JNIEnv* env, jobject j_iterable) {
00223   return
00224     build_cxx_system<Constraint_System>(env, j_iterable, build_cxx_constraint);
00225 }
00226 
00227 inline Generator_System
00228 build_cxx_generator_system(JNIEnv* env, jobject j_iterable) {
00229   return
00230     build_cxx_system<Generator_System>(env, j_iterable, build_cxx_generator);
00231 }
00232 
00233 inline Grid_Generator_System
00234 build_cxx_grid_generator_system(JNIEnv* env, jobject j_iterable) {
00235   return build_cxx_system<Grid_Generator_System> (env, j_iterable,
00236                                                   build_cxx_grid_generator);
00237 }
00238 
00239 } // namespace Java
00240 
00241 } // namespace Interfaces
00242 
00243 } // namespace Parma_Polyhedra_Library
00244 
00245 #endif // !defined(PPL_ppl_java_common_inlines_hh)