diff options
-rw-r--r-- | include/Makefile.am | 2 | ||||
-rw-r--r-- | include/my_compiler.h | 127 | ||||
-rw-r--r-- | include/my_global.h | 3 | ||||
-rw-r--r-- | sql/spatial.cc | 43 | ||||
-rw-r--r-- | sql/spatial.h | 28 | ||||
-rw-r--r-- | sql/sql_show.cc | 4 |
6 files changed, 166 insertions, 41 deletions
diff --git a/include/Makefile.am b/include/Makefile.am index 130517a405e..182011c25a3 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -37,7 +37,7 @@ noinst_HEADERS = config-win.h config-netware.h my_bit.h \ my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \ thr_lock.h t_ctype.h violite.h my_md5.h base64.h \ my_handler.h my_time.h my_vle.h my_user.h \ - my_libwrap.h my_stacktrace.h + my_libwrap.h my_stacktrace.h my_compiler.h EXTRA_DIST = mysql.h.pp mysql/plugin.h.pp diff --git a/include/my_compiler.h b/include/my_compiler.h new file mode 100644 index 00000000000..0a83c6587a5 --- /dev/null +++ b/include/my_compiler.h @@ -0,0 +1,127 @@ +#ifndef MY_COMPILER_INCLUDED +#define MY_COMPILER_INCLUDED + +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +/** + Header for compiler-dependent features. + + Intended to contain a set of reusable wrappers for preprocessor + macros, attributes, pragmas, and any other features that are + specific to a target compiler. +*/ + +#include <my_global.h> /* stddef.h offsetof */ + +/** + Compiler-dependent internal convenience macros. +*/ + +/* GNU C/C++ */ +#if defined __GNUC__ +/* Any after 2.95... */ +# define MY_ALIGN_EXT + +/* Microsoft Visual C++ */ +#elif defined _MSC_VER +# define MY_ALIGNOF(type) __alignof(type) +# define MY_ALIGNED(n) __declspec(align(n)) + +/* Oracle Solaris Studio */ +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# if (__SUNPRO_C >= 0x590) || (__SUNPRO_CC >= 0x590) +# define MY_ALIGN_EXT +# endif + +/* IBM XL C/C++ */ +#elif defined __xlC__ +# if __xlC__ >= 0x0600 +# define MY_ALIGN_EXT +# endif + +/* HP aCC */ +#elif defined(__HP_aCC) || defined(__HP_cc) +# if (__HP_aCC >= 60000) || (__HP_cc >= 60000) +# define MY_ALIGN_EXT +# endif +#endif + +#ifdef MY_ALIGN_EXT +/** Specifies the minimum alignment of a type. */ +# define MY_ALIGNOF(type) __alignof__(type) +/** Determine the alignment requirement of a type. */ +# define MY_ALIGNED(n) __attribute__((__aligned__((n)))) +#endif + +/** + Generic compiler-dependent features. +*/ +#ifndef MY_ALIGNOF +# ifdef __cplusplus + template<typename type> struct my_alignof_helper { char m1; type m2; }; + /* Invalid for non-POD types, but most compilers give the right answer. */ +# define MY_ALIGNOF(type) offsetof(my_alignof_helper<type>, m2) +# else +# define MY_ALIGNOF(type) offsetof(struct { char m1; type m2; }, m2) +# endif +#endif + +/** + C++ Type Traits +*/ + +#ifdef __cplusplus + +/** + Opaque storage with a particular alignment. +*/ +# if defined(MY_ALIGNED) +/* Partial specialization used due to MSVC++. */ +template<size_t alignment> struct my_alignment_imp; +template<> struct MY_ALIGNED(1) my_alignment_imp<1> {}; +template<> struct MY_ALIGNED(2) my_alignment_imp<2> {}; +template<> struct MY_ALIGNED(4) my_alignment_imp<4> {}; +template<> struct MY_ALIGNED(8) my_alignment_imp<8> {}; +template<> struct MY_ALIGNED(16) my_alignment_imp<16> {}; +/* ... expand as necessary. */ +# else +template<size_t alignment> +struct my_alignment_imp { double m1; }; +# endif + +/** + A POD type with a given size and alignment. + + @remark If the compiler does not support a alignment attribute + (MY_ALIGN macro), the default alignment of a double is + used instead. + + @tparam size The minimum size. + @tparam alignment The desired alignment: 1, 2, 4, 8 or 16. +*/ +template <size_t size, size_t alignment> +struct my_aligned_storage +{ + union + { + char data[size]; + my_alignment_imp<alignment> align; + }; +}; + +#endif /* __cplusplus */ + +#endif /* MY_COMPILER_INCLUDED */ diff --git a/include/my_global.h b/include/my_global.h index f03ed665d5a..6723267ae50 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -941,9 +941,6 @@ typedef long long my_ptrdiff_t; #define ADD_TO_PTR(ptr,size,type) (type) ((uchar*) (ptr)+size) #define PTR_BYTE_DIFF(A,B) (my_ptrdiff_t) ((uchar*) (A) - (uchar*) (B)) -#define MY_DIV_UP(A, B) (((A) + (B) - 1) / (B)) -#define MY_ALIGNED_BYTE_ARRAY(N, S, T) T N[MY_DIV_UP(S, sizeof(T))] - /* Custom version of standard offsetof() macro which can be used to get offsets of members in class for non-POD types (according to the current diff --git a/sql/spatial.cc b/sql/spatial.cc index 9114c81514d..11df6c00dc5 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -53,7 +53,7 @@ static Geometry::Class_info **ci_collection_end= Geometry::ci_collection+Geometry::wkb_last + 1; Geometry::Class_info::Class_info(const char *name, int type_id, - void(*create_func)(void *)): + create_geom_t create_func): m_type_id(type_id), m_create_func(create_func) { m_name.str= (char *) name; @@ -62,39 +62,39 @@ Geometry::Class_info::Class_info(const char *name, int type_id, ci_collection[type_id]= this; } -static void create_point(void *buffer) +static Geometry *create_point(char *buffer) { - new(buffer) Gis_point; + return new (buffer) Gis_point; } -static void create_linestring(void *buffer) +static Geometry *create_linestring(char *buffer) { - new(buffer) Gis_line_string; + return new (buffer) Gis_line_string; } -static void create_polygon(void *buffer) +static Geometry *create_polygon(char *buffer) { - new(buffer) Gis_polygon; + return new (buffer) Gis_polygon; } -static void create_multipoint(void *buffer) +static Geometry *create_multipoint(char *buffer) { - new(buffer) Gis_multi_point; + return new (buffer) Gis_multi_point; } -static void create_multipolygon(void *buffer) +static Geometry *create_multipolygon(char *buffer) { - new(buffer) Gis_multi_polygon; + return new (buffer) Gis_multi_polygon; } -static void create_multilinestring(void *buffer) +static Geometry *create_multilinestring(char *buffer) { - new(buffer) Gis_multi_line_string; + return new (buffer) Gis_multi_line_string; } -static void create_geometrycollection(void *buffer) +static Geometry *create_geometrycollection(char *buffer) { - new(buffer) Gis_geometry_collection; + return new (buffer) Gis_geometry_collection; } @@ -145,6 +145,15 @@ Geometry::Class_info *Geometry::find_class(const char *name, uint32 len) } +Geometry *Geometry::create_by_typeid(Geometry_buffer *buffer, int type_id) +{ + Class_info *ci; + if (!(ci= find_class(type_id))) + return NULL; + return (*ci->m_create_func)(buffer->data); +} + + Geometry *Geometry::construct(Geometry_buffer *buffer, const char *data, uint32 data_len) { @@ -179,9 +188,7 @@ Geometry *Geometry::create_from_wkt(Geometry_buffer *buffer, if (!(ci= find_class(name.str, name.length)) || wkt->reserve(1 + 4, 512)) return NULL; - (*ci->m_create_func)((void *)buffer); - Geometry *result= (Geometry *)buffer; - + Geometry *result= (*ci->m_create_func)(buffer->data); wkt->q_append((char) wkb_ndr); wkt->q_append((uint32) result->get_class_info()->m_type_id); if (trs->check_next_symbol('(') || diff --git a/sql/spatial.h b/sql/spatial.h index 86c2ed8c197..67edc077e04 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -16,6 +16,8 @@ #ifndef _spatial_h #define _spatial_h +#include <my_compiler.h> + #ifdef HAVE_SPATIAL const uint SRID_SIZE= 4; @@ -225,15 +227,18 @@ public: { wkb_xdr= 0, /* Big Endian */ wkb_ndr= 1 /* Little Endian */ - }; + }; + + /** Callback which creates Geometry objects on top of a given placement. */ + typedef Geometry *(*create_geom_t)(char *); class Class_info { public: LEX_STRING m_name; int m_type_id; - void (*m_create_func)(void *); - Class_info(const char *name, int type_id, void(*create_func)(void *)); + create_geom_t m_create_func; + Class_info(const char *name, int type_id, create_geom_t create_func); }; virtual const Class_info *get_class_info() const=0; @@ -263,15 +268,7 @@ public: virtual int geometry_n(uint32 num, String *result) const { return -1; } public: - static Geometry *create_by_typeid(Geometry_buffer *buffer, int type_id) - { - Class_info *ci; - if (!(ci= find_class((int) type_id))) - return NULL; - (*ci->m_create_func)((void *)buffer); - return my_reinterpret_cast(Geometry *)(buffer); - } - + static Geometry *create_by_typeid(Geometry_buffer *buffer, int type_id); static Geometry *construct(Geometry_buffer *buffer, const char *data, uint32 data_len); static Geometry *create_from_wkt(Geometry_buffer *buffer, @@ -528,11 +525,8 @@ public: const Class_info *get_class_info() const; }; -const int geometry_buffer_size= sizeof(Gis_point); -struct Geometry_buffer -{ - void *arr[(geometry_buffer_size - 1)/sizeof(void *) + 1]; -}; +struct Geometry_buffer : public + my_aligned_storage<sizeof(Gis_point), MY_ALIGNOF(Gis_point)> {}; #endif /*HAVE_SPATAIAL*/ #endif diff --git a/sql/sql_show.cc b/sql/sql_show.cc index ca0d16697cd..091bd09aa25 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2202,8 +2202,8 @@ static bool show_status_array(THD *thd, const char *wild, bool ucase_names, COND *cond) { - MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, long); - char * const buff= (char *) &buff_data; + my_aligned_storage<SHOW_VAR_FUNC_BUFF_SIZE, MY_ALIGNOF(long)> buffer; + char * const buff= buffer.data; char *prefix_end; /* the variable name should not be longer than 64 characters */ char name_buffer[64]; |