Import Cobalt 4.11837
diff --git a/src/base/platform_file_starboard.cc b/src/base/platform_file_starboard.cc
index c28fd65..cc116c6 100644
--- a/src/base/platform_file_starboard.cc
+++ b/src/base/platform_file_starboard.cc
@@ -161,21 +161,7 @@
int ReadPlatformFileAtCurrentPos(PlatformFile file, char *data, int size) {
base::ThreadRestrictions::AssertIOAllowed();
- if (file < 0 || size < 0)
- return -1;
-
- int bytes_read = 0;
- int rv;
- do {
- rv = SbFileRead(file, data, size);
- if (rv <= 0) {
- break;
- }
-
- bytes_read += rv;
- } while (bytes_read < size);
-
- return bytes_read ? bytes_read : rv;
+ return SbFileReadAll(file, data, size);
}
int ReadPlatformFileNoBestEffort(PlatformFile file,
@@ -251,22 +237,7 @@
const char* data,
int size) {
base::ThreadRestrictions::AssertIOAllowed();
- if (size < 0) {
- return -1;
- }
-
- int bytes_written = 0;
- int result;
- do {
- result = SbFileWrite(file, data, size);
- if (result <= 0) {
- break;
- }
-
- bytes_written += result;
- } while (bytes_written < size);
-
- return bytes_written ? bytes_written : result;
+ return SbFileWriteAll(file, data, size);
}
int WritePlatformFileCurPosNoBestEffort(PlatformFile file,
diff --git a/src/cobalt/base/tokens.h b/src/cobalt/base/tokens.h
index b2e24cd..cae31dd 100644
--- a/src/cobalt/base/tokens.h
+++ b/src/cobalt/base/tokens.h
@@ -83,6 +83,7 @@
MacroOpWithNameAndValue(class_selector_prefix, ".") \
MacroOpWithNameAndValue(comment_node_name, "#comment") \
MacroOpWithNameAndValue(document_name, "#document") \
+ MacroOpWithNameAndValue(domcontentloaded, "DOMContentLoaded") \
MacroOpWithNameAndValue(empty_pseudo_class_selector, "empty") \
MacroOpWithNameAndValue(focus_pseudo_class_selector, "focus") \
MacroOpWithNameAndValue(hover_pseudo_class_selector, "hover") \
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsSingleOperationInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsSingleOperationInterface.cc
index aaf933d..2bd13c6 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsSingleOperationInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsSingleOperationInterface.cc
@@ -58,13 +58,13 @@
bool* had_exception) const {
bool success = false;
base::optional<int32_t > cobalt_return_value;
+ JSAutoRequest auto_request(context_);
JSExceptionState* previous_exception_state = JS_SaveExceptionState(context_);
// This could be set to NULL if it was garbage collected.
JS::RootedObject implementing_object(context_, implementing_object_.Get());
DLOG_IF(WARNING, !implementing_object) << "Implementing object is NULL.";
if (implementing_object) {
- JSAutoRequest auto_request(context_);
JSAutoCompartment auto_compartment(context_, implementing_object);
// Get callable object.
diff --git a/src/cobalt/bindings/mozjs/templates/callback-interface.cc.template b/src/cobalt/bindings/mozjs/templates/callback-interface.cc.template
index f307bbc..115f228 100644
--- a/src/cobalt/bindings/mozjs/templates/callback-interface.cc.template
+++ b/src/cobalt/bindings/mozjs/templates/callback-interface.cc.template
@@ -56,13 +56,13 @@
{% if overload.type != 'void' %}
{{overload.type}} cobalt_return_value;
{% endif %}
+ JSAutoRequest auto_request(context_);
JSExceptionState* previous_exception_state = JS_SaveExceptionState(context_);
// This could be set to NULL if it was garbage collected.
JS::RootedObject implementing_object(context_, implementing_object_.Get());
DLOG_IF(WARNING, !implementing_object) << "Implementing object is NULL.";
if (implementing_object) {
- JSAutoRequest auto_request(context_);
JSAutoCompartment auto_compartment(context_, implementing_object);
// Get callable object.
diff --git a/src/cobalt/bindings/testing/global_interface_bindings_test.cc b/src/cobalt/bindings/testing/global_interface_bindings_test.cc
index 5f8b90c..5f50d61 100644
--- a/src/cobalt/bindings/testing/global_interface_bindings_test.cc
+++ b/src/cobalt/bindings/testing/global_interface_bindings_test.cc
@@ -38,7 +38,9 @@
} // namespace
TEST_F(GlobalInterfaceBindingsTest, GlobalWindowIsThis) {
- EXPECT_TRUE(EvaluateScript("window === this;", NULL));
+ std::string result;
+ EXPECT_TRUE(EvaluateScript("window === this;", &result));
+ EXPECT_STREQ("true", result.c_str());
}
TEST_F(GlobalInterfaceBindingsTest, GlobalOperation) {
diff --git a/src/cobalt/browser/cobalt.gyp b/src/cobalt/browser/cobalt.gyp
index 4f73099..f5bcfe9 100644
--- a/src/cobalt/browser/cobalt.gyp
+++ b/src/cobalt/browser/cobalt.gyp
@@ -94,4 +94,17 @@
},
],
+ 'conditions': [
+ ['final_executable_type == "shared_library"', {
+ 'targets': [
+ {
+ 'target_name': 'cobalt_bin',
+ 'type': 'executable',
+ 'dependencies': [
+ 'cobalt',
+ ],
+ },
+ ],
+ }],
+ ],
}
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id
index deb3c7d..70cae86 100644
--- a/src/cobalt/build/build.id
+++ b/src/cobalt/build/build.id
@@ -1 +1 @@
-11565
\ No newline at end of file
+11837
\ No newline at end of file
diff --git a/src/cobalt/build/config/base.gypi b/src/cobalt/build/config/base.gypi
index 7170bcb..02d4c04 100644
--- a/src/cobalt/build/config/base.gypi
+++ b/src/cobalt/build/config/base.gypi
@@ -128,6 +128,7 @@
# - scratch_surface_cache_size_in_bytes
# - surface_cache_size_in_bytes
# - image_cache_size_in_bytes
+ # - skia_glyph_atlas_width * skia_glyph_atlas_height
#
# The other caches affect CPU memory usage.
@@ -168,6 +169,15 @@
# image_cache_capacity_multiplier_when_playing_video.
'image_cache_capacity_multiplier_when_playing_video%': '1.0f',
+ # Determines the size in pixels of the glyph atlas where rendered glyphs are
+ # cached. The resulting memory usage is 2 bytes of GPU memory per pixel.
+ # When a value is used that is too small, thrashing may occur that will
+ # result in visible stutter. Such thrashing is more likely to occur when CJK
+ # language glyphs are rendered and when the size of the glyphs in pixels is
+ # larger, such as for higher resolution displays.
+ 'skia_glyph_atlas_width%': '2048',
+ 'skia_glyph_atlas_height%': '2048',
+
# Compiler configuration.
# The following variables are used to specify compiler and linker
@@ -268,13 +278,25 @@
'include_dirs': [ '<(DEPTH)' ],
'libraries': [ '<@(platform_libraries)' ],
- # TODO: This is needed to support the option to include
- # posix_emulation.h to all compiled source files. This dependency should
- # be refactored and removed.
- 'include_dirs_target': [
- '<(DEPTH)/lbshell/src',
- ],
'conditions': [
+ ['final_executable_type=="shared_library"', {
+ 'target_conditions': [
+ ['_toolset=="target"', {
+ 'defines': [
+ # Rewrite main() functions into StarboardMain. TODO: This is a
+ # hack, it would be better to be more surgical, here.
+ 'main=StarboardMain',
+ ],
+ 'cflags': [
+ # To link into a shared library on Linux and similar platforms,
+ # the compiler must be told to generate Position Independent Code.
+ # This appears to cause errors when linking the code statically,
+ # however.
+ '-fPIC',
+ ],
+ }],
+ ],
+ }],
['posix_emulation_target_type == "shared_library"', {
'defines': [
'__LB_BASE_SHARED__=1',
@@ -294,6 +316,10 @@
'<(DEPTH)/lbshell/src/platform/<(target_arch)/posix_emulation/lb_shell',
# headers that we don't need, but should exist somewhere in the path:
'<(DEPTH)/lbshell/src/platform/<(target_arch)/posix_emulation/place_holders',
+ # TODO: This is needed to support the option to include
+ # posix_emulation.h to all compiled source files. This dependency
+ # should be refactored and removed.
+ '<(DEPTH)/lbshell/src',
],
}], # OS == "lb_shell"
['OS == "starboard"', {
diff --git a/src/cobalt/dom/event_target.cc b/src/cobalt/dom/event_target.cc
index 87553ff..39175e3 100644
--- a/src/cobalt/dom/event_target.cc
+++ b/src/cobalt/dom/event_target.cc
@@ -107,6 +107,9 @@
void EventTarget::PostToDispatchEventAndRunCallback(
const tracked_objects::Location& location, base::Token event_name,
const base::Closure& callback) {
+ if (!MessageLoop::current()) {
+ return;
+ }
MessageLoop::current()->PostTask(
location,
base::Bind(base::IgnoreResult(&EventTarget::DispatchEventAndRunCallback),
diff --git a/src/cobalt/dom/event_target.h b/src/cobalt/dom/event_target.h
index 462d7a6..3fc4df9 100644
--- a/src/cobalt/dom/event_target.h
+++ b/src/cobalt/dom/event_target.h
@@ -68,12 +68,14 @@
void DispatchEventAndRunCallback(base::Token event_name,
const base::Closure& dispatched_callback);
- // Posts a task on the current message loop to dispatch event.
+ // Posts a task on the current message loop to dispatch event. It does nothing
+ // if there is no current message loop.
void PostToDispatchEvent(const tracked_objects::Location& location,
base::Token event_name);
// Posts a task on the current message loop to dispatch event, and runs
- // dispatched_callback after finish.
+ // dispatched_callback after finish. It does nothing if there is no current
+ // message loop.
void PostToDispatchEventAndRunCallback(
const tracked_objects::Location& location, base::Token event_name,
const base::Closure& dispatched_callback);
diff --git a/src/cobalt/dom/media_error.h b/src/cobalt/dom/media_error.h
index 339c386..124b437 100644
--- a/src/cobalt/dom/media_error.h
+++ b/src/cobalt/dom/media_error.h
@@ -44,7 +44,7 @@
// Web API: MediaError
//
- Code code() const { return code_; }
+ uint32 code() const { return code_; }
DEFINE_WRAPPABLE_TYPE(MediaError);
diff --git a/src/cobalt/dom_parser/libxml_html_parser_wrapper.cc b/src/cobalt/dom_parser/libxml_html_parser_wrapper.cc
index e65ef8f..75e760b 100644
--- a/src/cobalt/dom_parser/libxml_html_parser_wrapper.cc
+++ b/src/cobalt/dom_parser/libxml_html_parser_wrapper.cc
@@ -110,9 +110,7 @@
return;
}
- if (!IsStringUTF8(std::string(data, size))) {
- static const char* kWarningNotUTF8 = "Ignoring non-UTF8 HTML input.";
- OnParsingIssue(kWarning, kWarningNotUTF8);
+ if (CheckInputAndUpdateSeverity(data, size) >= kError) {
return;
}
@@ -127,7 +125,7 @@
NULL /*filename*/, XML_CHAR_ENCODING_UTF8);
if (!html_parser_context_) {
- static const char* kErrorUnableCreateParser =
+ static const char kErrorUnableCreateParser[] =
"Unable to create the libxml2 parser.";
OnParsingIssue(kFatal, kErrorUnableCreateParser);
} else {
@@ -149,12 +147,8 @@
}
if (html_parser_context_) {
- // TODO: The check on issue level is a workaround for the fact that libxml
- // doesn't recover fully from error related to encoding.
- if (issue_level() <= kWarning) {
- htmlParseChunk(html_parser_context_, NULL, 0,
- 1 /*terminate*/); // Triggers EndDocument
- }
+ htmlParseChunk(html_parser_context_, NULL, 0,
+ 1 /*terminate*/); // Triggers EndDocument
if (IsFullDocument()) {
document()->DecreaseLoadingCounterAndMaybeDispatchLoadEvent();
}
diff --git a/src/cobalt/dom_parser/libxml_parser_wrapper.cc b/src/cobalt/dom_parser/libxml_parser_wrapper.cc
index 3acaf88..67521c2 100644
--- a/src/cobalt/dom_parser/libxml_parser_wrapper.cc
+++ b/src/cobalt/dom_parser/libxml_parser_wrapper.cc
@@ -19,6 +19,7 @@
#include "base/logging.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
+#include "cobalt/base/tokens.h"
#include "cobalt/dom/cdata_section.h"
#include "cobalt/dom/comment.h"
#include "cobalt/dom/element.h"
@@ -150,6 +151,10 @@
if (!node_stack_.empty() && !error_callback_.is_null()) {
error_callback_.Run("Node stack not empty at end of document.");
}
+
+ if (IsFullDocument()) {
+ document_->PostToDispatchEvent(FROM_HERE, base::Tokens::domcontentloaded());
+ }
}
void LibxmlParserWrapper::OnStartElement(
@@ -214,8 +219,8 @@
void LibxmlParserWrapper::OnParsingIssue(IssueSeverity severity,
const std::string& message) {
- if (severity > issue_level_) {
- issue_level_ = severity;
+ if (severity > max_severity_) {
+ max_severity_ = severity;
}
if (severity < LibxmlParserWrapper::kFatal) {
LOG(WARNING) << message;
@@ -230,5 +235,31 @@
node_stack_.top()->AppendChild(new dom::CDATASection(document_, value));
}
+LibxmlParserWrapper::IssueSeverity
+LibxmlParserWrapper::CheckInputAndUpdateSeverity(const char* data,
+ size_t size) {
+ if (max_severity_ >= kError) {
+ return max_severity_;
+ }
+
+ // Check the total input size.
+ total_input_size_ += size;
+ if (total_input_size_ > kMaxTotalInputSize) {
+ static const char kErrorTooLong[] = "Parser input is too long.";
+ OnParsingIssue(kError, kErrorTooLong);
+ return max_severity_;
+ }
+
+ // Check the encoding of the input.
+ if (!IsStringUTF8(std::string(data, size))) {
+ static const char kErrorNotUTF8[] =
+ "Parser input contains non-UTF8 characters.";
+ OnParsingIssue(kError, kErrorNotUTF8);
+ return max_severity_;
+ }
+
+ return max_severity_;
+}
+
} // namespace dom_parser
} // namespace cobalt
diff --git a/src/cobalt/dom_parser/libxml_parser_wrapper.h b/src/cobalt/dom_parser/libxml_parser_wrapper.h
index 61f3d04..bbeb21a 100644
--- a/src/cobalt/dom_parser/libxml_parser_wrapper.h
+++ b/src/cobalt/dom_parser/libxml_parser_wrapper.h
@@ -92,7 +92,8 @@
first_chunk_location_(first_chunk_location),
error_callback_(error_callback),
depth_limit_exceeded_(false),
- issue_level_(kNoIssue) {}
+ max_severity_(kNoIssue),
+ total_input_size_(0) {}
virtual ~LibxmlParserWrapper() {}
// These functions are for Libxml interface, calls are forwarded here by
@@ -120,6 +121,9 @@
// Returns true when the input is a full document, false when it's a fragment.
bool IsFullDocument() { return document_ == parent_node_; }
+ // Checks the input, updates and returns the maximum issue severity.
+ IssueSeverity CheckInputAndUpdateSeverity(const char* data, size_t size);
+
const scoped_refptr<dom::Document>& document() { return document_; }
const base::SourceLocation& first_chunk_location() {
return first_chunk_location_;
@@ -128,13 +132,14 @@
return error_callback_;
}
- IssueSeverity issue_level() const { return issue_level_; }
-
const std::stack<scoped_refptr<dom::Node> >& node_stack() {
return node_stack_;
}
private:
+ // Maximum total input size, 1MB.
+ static const size_t kMaxTotalInputSize = 1 * 1024 * 1024;
+
const scoped_refptr<dom::Document> document_;
const scoped_refptr<dom::Node> parent_node_;
const scoped_refptr<dom::Node> reference_node_;
@@ -145,7 +150,8 @@
const base::Callback<void(const std::string&)> error_callback_;
bool depth_limit_exceeded_;
- IssueSeverity issue_level_;
+ IssueSeverity max_severity_;
+ size_t total_input_size_;
std::stack<scoped_refptr<dom::Node> > node_stack_;
diff --git a/src/cobalt/dom_parser/libxml_xml_parser_wrapper.cc b/src/cobalt/dom_parser/libxml_xml_parser_wrapper.cc
index edab9f0..c933f5e 100644
--- a/src/cobalt/dom_parser/libxml_xml_parser_wrapper.cc
+++ b/src/cobalt/dom_parser/libxml_xml_parser_wrapper.cc
@@ -79,9 +79,7 @@
return;
}
- if (!IsStringUTF8(std::string(data, size))) {
- static const char* kWarningNotUTF8 = "Ignoring non-UTF8 XML input.";
- OnParsingIssue(kWarning, kWarningNotUTF8);
+ if (CheckInputAndUpdateSeverity(data, size) >= kError) {
return;
}
diff --git a/src/cobalt/layout/render_tree_animations.h b/src/cobalt/layout/render_tree_animations.h
index 0c8a862..e2087ab 100644
--- a/src/cobalt/layout/render_tree_animations.h
+++ b/src/cobalt/layout/render_tree_animations.h
@@ -93,11 +93,13 @@
populate_base_style_function.Run(css_computed_style_declaration.data(),
base_style);
+ web_animations::BakedAnimationSet baked_animation_set(
+ *css_computed_style_declaration.animations());
+
node_animation_map_builder->Add(
target_node, base::Bind(&ApplyAnimation<T>, apply_style_function,
- web_animations::BakedAnimationSet(
- *css_computed_style_declaration.animations()),
- base_style));
+ baked_animation_set, base_style),
+ baked_animation_set.end_time());
}
} // namespace layout
diff --git a/src/cobalt/layout_tests/layout_benchmarks.cc b/src/cobalt/layout_tests/layout_benchmarks.cc
index 164741c..bace1ed 100644
--- a/src/cobalt/layout_tests/layout_benchmarks.cc
+++ b/src/cobalt/layout_tests/layout_benchmarks.cc
@@ -45,14 +45,18 @@
RendererBenchmarkRunner()
: done_gathering_samples_(true, false),
system_window_(system_window::CreateSystemWindow(
- &event_dispatcher_, math::Size(kViewportWidth, kViewportHeight))),
- renderer_module_(system_window_.get(),
- renderer::RendererModule::Options()) {}
+ &event_dispatcher_, math::Size(kViewportWidth, kViewportHeight))) {
+ // Since we'd like to measure the renderer, we force it to rasterize each
+ // frame despite the fact that the render tree may not be changing.
+ renderer::RendererModule::Options renderer_options;
+ renderer_options.submit_even_if_render_tree_is_unchanged = true;
+ renderer_module_.emplace(system_window_.get(), renderer_options);
+ }
// Return the resource provider from the internal renderer so that it can
// be used during layout.
render_tree::ResourceProvider* GetResourceProvider() {
- return renderer_module_.pipeline()->GetResourceProvider();
+ return renderer_module_->pipeline()->GetResourceProvider();
}
// Run the renderer benchmarks and perform the measurements.
@@ -67,11 +71,11 @@
submission_with_callback.on_rasterized_callback = base::Bind(
&RendererBenchmarkRunner::OnSubmitComplete, base::Unretained(this));
- renderer_module_.pipeline()->Submit(submission_with_callback);
+ renderer_module_->pipeline()->Submit(submission_with_callback);
done_gathering_samples_.Wait();
- renderer_module_.pipeline()->Clear();
+ renderer_module_->pipeline()->Clear();
}
private:
@@ -93,7 +97,7 @@
base::EventDispatcher event_dispatcher_;
scoped_ptr<system_window::SystemWindow> system_window_;
- renderer::RendererModule renderer_module_;
+ base::optional<renderer::RendererModule> renderer_module_;
};
} // namespace
diff --git a/src/cobalt/layout_tests/testdata/cobalt/100-dynamically-created-nested-elements.html b/src/cobalt/layout_tests/testdata/cobalt/100-dynamically-created-nested-elements.html
index 498e1a7..2c692ea 100644
--- a/src/cobalt/layout_tests/testdata/cobalt/100-dynamically-created-nested-elements.html
+++ b/src/cobalt/layout_tests/testdata/cobalt/100-dynamically-created-nested-elements.html
@@ -16,12 +16,12 @@
that max element depth is 32. -->
<script>
- var parent = document.body;
+ var parent_element = document.body;
for (var i = 1; i <= 100; i++) {
var new_child = document.createElement("span");
new_child.textContent = i + " ";
- parent.appendChild(new_child);
- parent = new_child;
+ parent_element.appendChild(new_child);
+ parent_element = new_child;
}
</script>
diff --git a/src/cobalt/media/media_buffer_allocator.h b/src/cobalt/media/media_buffer_allocator.h
new file mode 100644
index 0000000..ef7f620
--- /dev/null
+++ b/src/cobalt/media/media_buffer_allocator.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef COBALT_MEDIA_MEDIA_BUFFER_ALLOCATOR_H_
+#define COBALT_MEDIA_MEDIA_BUFFER_ALLOCATOR_H_
+
+#include "base/optional.h"
+#include "nb/memory_pool.h"
+
+namespace cobalt {
+namespace media {
+
+class MediaBufferAllocator {
+ public:
+ MediaBufferAllocator(void* pool, size_t main_pool_size,
+ size_t small_allocation_pool_size,
+ size_t small_allocation_threshold)
+ : pool_(reinterpret_cast<uint8*>(pool)),
+ main_pool_size_(main_pool_size),
+ small_allocation_pool_size_(small_allocation_pool_size),
+ small_allocation_threshold_(small_allocation_threshold),
+ main_pool_(pool_, main_pool_size_, true, /* thread_safe */
+ true /* verify_full_capacity */) {
+ if (small_allocation_pool_size_ > 0u) {
+ DCHECK_GT(small_allocation_threshold_, 0u);
+ small_allocation_pool_.emplace(pool_ + main_pool_size_,
+ small_allocation_pool_size_,
+ true, /* thread_safe */
+ true /* verify_full_capacity */);
+ } else {
+ DCHECK_EQ(small_allocation_pool_size_, 0u);
+ DCHECK_EQ(small_allocation_threshold_, 0u);
+ }
+ }
+
+ void* Allocate(size_t size, size_t alignment) {
+ void* p = NULL;
+ if (size < small_allocation_threshold_ && small_allocation_pool_) {
+ p = small_allocation_pool_->Allocate(size, alignment);
+ }
+ if (!p) {
+ p = main_pool_.Allocate(size, alignment);
+ }
+ if (!p && small_allocation_pool_) {
+ p = small_allocation_pool_->Allocate(size, alignment);
+ }
+ return p;
+ }
+
+ void Free(void* p) {
+ if (p >= pool_ + main_pool_size_ && small_allocation_pool_) {
+ DCHECK_LT(p, pool_ + main_pool_size_ + small_allocation_pool_size_);
+ small_allocation_pool_->Free(p);
+ return;
+ }
+ DCHECK_GE(p, pool_);
+ DCHECK_LT(p, pool_ + main_pool_size_);
+ main_pool_.Free(p);
+ }
+
+ private:
+ uint8* pool_;
+ size_t main_pool_size_;
+ size_t small_allocation_pool_size_;
+ size_t small_allocation_threshold_;
+
+ nb::MemoryPool main_pool_;
+ base::optional<nb::MemoryPool> small_allocation_pool_;
+
+ DISALLOW_COPY_AND_ASSIGN(MediaBufferAllocator);
+};
+
+} // namespace media
+} // namespace cobalt
+
+#endif // COBALT_MEDIA_MEDIA_BUFFER_ALLOCATOR_H_
diff --git a/src/cobalt/media/shell_media_platform_starboard.cc b/src/cobalt/media/shell_media_platform_starboard.cc
index 096b670..9b9bf31 100644
--- a/src/cobalt/media/shell_media_platform_starboard.cc
+++ b/src/cobalt/media/shell_media_platform_starboard.cc
@@ -38,6 +38,8 @@
const size_t kGPUMemoryBufferBudget = SB_MEDIA_GPU_BUFFER_BUDGET;
const size_t kMainMemoryBufferBudget = SB_MEDIA_MAIN_BUFFER_BUDGET;
+const size_t kSmallAllocationThreshold = 768U;
+
} // namespace
ShellMediaPlatformStarboard::ShellMediaPlatformStarboard(
@@ -58,7 +60,7 @@
gpu_memory_pool_.reset(new nb::MemoryPool(
gpu_memory_buffer_space_->GetMemory(),
gpu_memory_buffer_space_->GetSizeInBytes(), true, /* thread_safe */
- true /* verify_full_capacity */));
+ true /* verify_full_capacity */, kSmallAllocationThreshold));
}
DCHECK_LE(0, kMainMemoryBufferBudget > 0);
@@ -68,7 +70,8 @@
main_memory_pool_.reset(new nb::MemoryPool(main_memory_buffer_space_.get(),
kMainMemoryBufferBudget,
true, /* thread_safe */
- true /* verify_full_capacity */));
+ true, /* verify_full_capacity */
+ kSmallAllocationThreshold));
ShellBufferFactory::Initialize();
ShellAudioStreamer::Initialize();
diff --git a/src/cobalt/render_tree/animations/animate_node.cc b/src/cobalt/render_tree/animations/animate_node.cc
index d51732a..6363ec9 100644
--- a/src/cobalt/render_tree/animations/animate_node.cc
+++ b/src/cobalt/render_tree/animations/animate_node.cc
@@ -16,6 +16,8 @@
#include "cobalt/render_tree/animations/animate_node.h"
+#include <algorithm>
+
#include "base/debug/trace_event.h"
#include "cobalt/base/enable_if.h"
#include "cobalt/base/polymorphic_downcast.h"
@@ -63,7 +65,9 @@
public:
TraverseListBuilder(const AnimateNode::Builder::InternalMap& animation_map,
TraverseList* traverse_list)
- : animation_map_(animation_map), traverse_list_(traverse_list) {}
+ : animation_map_(animation_map),
+ traverse_list_(traverse_list),
+ expiry_(-base::TimeDelta::Max()) {}
void Visit(animations::AnimateNode* animate) OVERRIDE;
void Visit(CompositionNode* composition) OVERRIDE { VisitNode(composition); }
@@ -108,6 +112,9 @@
// this visitor's associated node with in its list of child nodes.
scoped_refptr<Node> replace_with_;
+ // The time after which all animations will have completed and be constant.
+ base::TimeDelta expiry_;
+
friend class AnimateNode;
};
@@ -134,6 +141,9 @@
// maintain the invariant that an AnimateNode does not contain any
// AnimateNode descendants.
replace_with_ = animate->source_;
+
+ // Update our expiry in accordance with the sub-AnimateNode's expiry.
+ expiry_ = std::max(expiry_, animate->expiry());
}
template <typename T>
@@ -197,6 +207,7 @@
Node* node, AnimateNode::Builder::InternalMap::const_iterator found) {
if (found != animation_map_.end()) {
traverse_list_->push_back(TraverseListEntry(node, found->second));
+ expiry_ = std::max(expiry_, found->second->GetExpiry());
} else {
traverse_list_->push_back(TraverseListEntry(node));
}
@@ -394,6 +405,8 @@
std::reverse(traverse_list_.begin(), traverse_list_.end());
DCHECK(source_.get() == traverse_list_.begin()->node);
}
+
+ expiry_ = traverse_list_builder.expiry_;
}
} // namespace animations
diff --git a/src/cobalt/render_tree/animations/animate_node.h b/src/cobalt/render_tree/animations/animate_node.h
index 4b9bfae..b5a11e1 100644
--- a/src/cobalt/render_tree/animations/animate_node.h
+++ b/src/cobalt/render_tree/animations/animate_node.h
@@ -73,9 +73,19 @@
// Convenience method to attach a single animation to a target node.
template <typename T>
void Add(const scoped_refptr<T>& target_node,
+ const typename Animation<T>::Function& single_animation,
+ base::TimeDelta expiry) {
+ AddInternal(target_node,
+ scoped_refptr<AnimationListBase>(
+ new AnimationList<T>(single_animation, expiry)));
+ }
+
+ template <typename T>
+ void Add(const scoped_refptr<T>& target_node,
const typename Animation<T>::Function& single_animation) {
- AddInternal(target_node, scoped_refptr<AnimationListBase>(
- new AnimationList<T>(single_animation)));
+ AddInternal(target_node,
+ scoped_refptr<AnimationListBase>(new AnimationList<T>(
+ single_animation, base::TimeDelta::Max())));
}
// Merge all mappings from another AnimateNode::Builder into this one.
@@ -137,6 +147,12 @@
// Returns the sub-tree for which the animations apply to.
const scoped_refptr<Node> source() const { return source_; }
+ // Returns the time at which all animations will have completed, or
+ // base::TimeDelta::Max() if they will never complete.
+ // It will be true that AnimateNode::Apply(x) == AnimateNode::Apply(y) for
+ // all x, y >= expiry().
+ const base::TimeDelta& expiry() const { return expiry_; }
+
private:
// A helper render tree visitor class used to compile sub render-tree
// animations.
@@ -168,6 +184,7 @@
// that guides us towards all nodes that need to be animated.
TraverseList traverse_list_;
scoped_refptr<Node> source_;
+ base::TimeDelta expiry_;
};
} // namespace animations
diff --git a/src/cobalt/render_tree/animations/animation_list.h b/src/cobalt/render_tree/animations/animation_list.h
index a37bd3f..89c12fd 100644
--- a/src/cobalt/render_tree/animations/animation_list.h
+++ b/src/cobalt/render_tree/animations/animation_list.h
@@ -77,6 +77,9 @@
// letting us collect animation lists in a single collection, at the cost of
// needing to type cast in a few places.
class AnimationListBase : public base::RefCountedThreadSafe<AnimationListBase> {
+ public:
+ virtual base::TimeDelta GetExpiry() const = 0;
+
protected:
virtual ~AnimationListBase() {}
friend class base::RefCountedThreadSafe<AnimationListBase>;
@@ -99,24 +102,33 @@
struct Builder {
DECLARE_AS_MOVABLE(Builder);
- Builder() {}
+ Builder() : expiry(base::TimeDelta::Max()) {}
explicit Builder(Moved moved) { animations.swap(moved->animations); }
- explicit Builder(const typename Animation<T>::Function& single_animation) {
+ explicit Builder(const typename Animation<T>::Function& single_animation,
+ base::TimeDelta expiry)
+ : expiry(expiry) {
animations.push_back(single_animation);
}
InternalList animations;
+ // When do the animations expire? base::TimeDelta::Max() implies that they
+ // never expire.
+ base::TimeDelta expiry;
};
explicit AnimationList(typename Builder::Moved builder) : data_(builder) {}
// Convenience constructor to allow for easy construction of AnimationLists
- // containing a single Animation.
+ // containing a single Animation. |expiry| indicates the time at which the
+ // animation ceases, or base::TimeDelta::Max() if that never occurs.
explicit AnimationList(
- const typename Animation<T>::Function& single_animation)
- : data_(single_animation) {}
+ const typename Animation<T>::Function& single_animation,
+ base::TimeDelta expiry)
+ : data_(single_animation, expiry) {}
const Builder& data() const { return data_; }
+ base::TimeDelta GetExpiry() const OVERRIDE { return data_.expiry; }
+
private:
~AnimationList() OVERRIDE {}
diff --git a/src/cobalt/renderer/animations_test.cc b/src/cobalt/renderer/animations_test.cc
index 033a78f..b46c59e 100644
--- a/src/cobalt/renderer/animations_test.cc
+++ b/src/cobalt/renderer/animations_test.cc
@@ -1,4 +1,4 @@
-/*
+ /*
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -171,7 +171,7 @@
Pipeline pipeline(
base::Bind(render_module_options.create_rasterizer_function,
graphics_context.get(), render_module_options),
- dummy_output_surface, NULL);
+ dummy_output_surface, NULL, true);
// Our test render tree will consist of only a single ImageNode.
scoped_refptr<ImageNode> test_node = new ImageNode(
diff --git a/src/cobalt/renderer/pipeline.cc b/src/cobalt/renderer/pipeline.cc
index a1c5aba..9974067 100644
--- a/src/cobalt/renderer/pipeline.cc
+++ b/src/cobalt/renderer/pipeline.cc
@@ -65,12 +65,15 @@
Pipeline::Pipeline(const CreateRasterizerFunction& create_rasterizer_function,
const scoped_refptr<backend::RenderTarget>& render_target,
- backend::GraphicsContext* graphics_context)
+ backend::GraphicsContext* graphics_context,
+ bool submit_even_if_render_tree_is_unchanged)
: rasterizer_created_event_(true, false),
render_target_(render_target),
graphics_context_(graphics_context),
rasterizer_thread_("Rasterizer"),
submission_disposal_thread_("Rasterizer Submission Disposal"),
+ submit_even_if_render_tree_is_unchanged_(
+ submit_even_if_render_tree_is_unchanged),
rasterize_current_tree_interval_timer_(
"Renderer.Rasterize.Interval",
kRasterizeCurrentTreeTimerTimeIntervalInMs),
@@ -121,6 +124,11 @@
base::Unretained(&submission_queue_shutdown)));
submission_queue_shutdown.Wait();
+ // This potential reference to a render tree whose animations may have ended
+ // must be destroyed before we shutdown the rasterizer thread since it may
+ // contain references to render tree nodes and resources.
+ last_rendered_expired_render_tree_ = NULL;
+
// Submit a shutdown task to the rasterizer thread so that it can shutdown
// anything that must be shutdown from that thread.
rasterizer_thread_.message_loop()->PostTask(
@@ -190,11 +198,11 @@
// Start the rasterization timer if it is not yet started.
if (!rasterize_timer_) {
- // We submit render trees as fast as the rasterizer can consume them.
- // Practically, this will result in the rate being limited to the
- // display's refresh rate.
+ // We artificially limit the period between submissions to 15ms, in case
+ // a platform does not rate limit itself during swaps. This limit may need
+ // to be reduced if we wish to support 120 FPS animations.
rasterize_timer_.emplace(
- FROM_HERE, base::TimeDelta(),
+ FROM_HERE, base::TimeDelta::FromMilliseconds(15),
base::Bind(&Pipeline::RasterizeCurrentTree, base::Unretained(this)),
true, true);
rasterize_timer_->Reset();
@@ -219,14 +227,37 @@
TRACE_EVENT0("cobalt::renderer", "Pipeline::RasterizeCurrentTree()");
base::TimeTicks now = base::TimeTicks::Now();
+ Submission submission = submission_queue_->GetCurrentSubmission(now);
+
+ // If our render tree hasn't changed from the one that was previously rendered
+ // and the animations on the previously rendered tree have expired, and it's
+ // okay on this system to not flip the display buffer frequently, then we
+ // can just not do anything here.
+ if (!submit_even_if_render_tree_is_unchanged_ &&
+ submission.render_tree == last_rendered_expired_render_tree_) {
+ return;
+ }
+
rasterize_current_tree_interval_timer_.Start(now);
rasterize_current_tree_timer_.Start(now);
// Rasterize the last submitted render tree.
- RasterizeSubmissionToRenderTarget(
- submission_queue_->GetCurrentSubmission(now), render_target_);
+ RasterizeSubmissionToRenderTarget(submission, render_target_);
rasterize_current_tree_timer_.Stop();
+
+ // Check whether the animations in the render tree that was just rasterized
+ // have expired or not, and if so, mark that down so that if we see it in
+ // the future we don't spend the time re-rendering it.
+ if (!submit_even_if_render_tree_is_unchanged_) {
+ render_tree::animations::AnimateNode* animate_node =
+ base::polymorphic_downcast<render_tree::animations::AnimateNode*>(
+ submission.render_tree.get());
+ last_rendered_expired_render_tree_ =
+ animate_node->expiry() <= submission.time_offset
+ ? submission.render_tree
+ : NULL;
+ }
}
void Pipeline::RasterizeSubmissionToRenderTarget(
diff --git a/src/cobalt/renderer/pipeline.h b/src/cobalt/renderer/pipeline.h
index ad05b29..975f593 100644
--- a/src/cobalt/renderer/pipeline.h
+++ b/src/cobalt/renderer/pipeline.h
@@ -59,7 +59,8 @@
// thread safe objects.
Pipeline(const CreateRasterizerFunction& create_rasterizer_function,
const scoped_refptr<backend::RenderTarget>& render_target,
- backend::GraphicsContext* graphics_context);
+ backend::GraphicsContext* graphics_context,
+ bool submit_even_if_render_tree_is_unchanged);
~Pipeline();
// Submit a new render tree to the renderer pipeline. After calling this
@@ -166,6 +167,15 @@
// the future.
base::optional<SubmissionQueue> submission_queue_;
+ // Keep track of the last render tree we rendered whose animations have
+ // expired so that if we see that we are asked to rasterize that render tree
+ // again, we know that we do not have to do anything.
+ scoped_refptr<render_tree::Node> last_rendered_expired_render_tree_;
+
+ // If true, we will submit the current render tree to the rasterizer every
+ // frame, even if it hasn't changed.
+ const bool submit_even_if_render_tree_is_unchanged_;
+
// Timers for tracking how frequently |RasterizeCurrentTree| is called and
// the amount of time spent in |RasterizeCurrentTree| each call.
base::CValTimeIntervalTimer<base::CValPublic>
diff --git a/src/cobalt/renderer/pipeline_test.cc b/src/cobalt/renderer/pipeline_test.cc
index db7585a..c258641 100644
--- a/src/cobalt/renderer/pipeline_test.cc
+++ b/src/cobalt/renderer/pipeline_test.cc
@@ -88,15 +88,30 @@
submission_count_ = 0;
start_time_ = base::TimeTicks::Now();
pipeline_.reset(new Pipeline(
- base::Bind(&CreateMockRasterizer, &submission_count_), NULL, NULL));
-
- // We create a render tree here composed of only a single, empty
- // CompositionNode that is meant to act as a dummy/placeholder.
- dummy_render_tree_ = scoped_refptr<cobalt::render_tree::Node>(
- new cobalt::render_tree::CompositionNode(
- cobalt::render_tree::CompositionNode::Builder()));
+ base::Bind(&CreateMockRasterizer, &submission_count_), NULL, NULL,
+ true));
}
+ static void DummyAnimateFunction(
+ cobalt::render_tree::CompositionNode::Builder* composition_node_builder,
+ base::TimeDelta time) {}
+
+ // We create a render tree composed of only a single, empty CompositionNode
+ // that is meant to act as a dummy/placeholder. It is animated to ensure that
+ // it changes every frame and so the Pipeline must rasterize it each frame.
+ scoped_refptr<cobalt::render_tree::Node> MakeDummyAnimatedRenderTree() {
+ scoped_refptr<cobalt::render_tree::CompositionNode> dummy_node(
+ new cobalt::render_tree::CompositionNode(
+ cobalt::render_tree::CompositionNode::Builder()));
+
+ cobalt::render_tree::animations::AnimateNode::Builder animate_builder;
+ animate_builder.Add(dummy_node, base::Bind(&DummyAnimateFunction));
+ scoped_refptr<cobalt::render_tree::animations::AnimateNode> animate_node(
+ new cobalt::render_tree::animations::AnimateNode(animate_builder,
+ dummy_node));
+
+ return animate_node;
+ }
// Checks that Submit() was called on mock_rasterizer_ the expect number of
// times given the refresh rate and lower/upper bounds for how long the
// pipeline was active.
@@ -131,7 +146,6 @@
base::TimeTicks start_time_; // Record the time that we started the pipeline.
scoped_ptr<Pipeline> pipeline_;
- scoped_refptr<cobalt::render_tree::Node> dummy_render_tree_;
int submission_count_;
};
@@ -146,7 +160,8 @@
TEST_F(
RendererPipelineTest,
FLAKY_RasterizerSubmitCalledAtExpectedFrequencyAfterSinglePipelineSubmit) {
- pipeline_->Submit(cobalt::renderer::Submission(dummy_render_tree_));
+ pipeline_->Submit(
+ cobalt::renderer::Submission(MakeDummyAnimatedRenderTree()));
// Wait a little bit to give the pipeline some time to rasterize the submitted
// render tree.
@@ -179,7 +194,8 @@
break;
}
- pipeline_->Submit(cobalt::renderer::Submission(dummy_render_tree_));
+ pipeline_->Submit(
+ cobalt::renderer::Submission(MakeDummyAnimatedRenderTree()));
const base::TimeDelta kSubmitDelay(base::TimeDelta::FromMilliseconds(1));
// While we want to submit faster than the rasterizer is rasterizing,
diff --git a/src/cobalt/renderer/rasterizer/skia/skia/skia_library.gypi b/src/cobalt/renderer/rasterizer/skia/skia/skia_library.gypi
index 49aee75..dba75b6 100644
--- a/src/cobalt/renderer/rasterizer/skia/skia/skia_library.gypi
+++ b/src/cobalt/renderer/rasterizer/skia/skia/skia_library.gypi
@@ -151,6 +151,9 @@
'<(DEPTH)/third_party/skia/src/fonts/SkGScalerContext.h',
'<(DEPTH)/third_party/skia/src/fonts/SkTestScalerContext.cpp',
'<(DEPTH)/third_party/skia/src/fonts/SkTestScalerContext.h',
+
+ # Conflicts with cobalt implementation.
+ '<(DEPTH)/third_party/skia/src/gpu/gl/GrGLCreateNativeInterface_none.cpp',
],
# Exclude Skia OpenGL backend source files.
diff --git a/src/cobalt/renderer/renderer_module.cc b/src/cobalt/renderer/renderer_module.cc
index 5806add..ebe8531 100644
--- a/src/cobalt/renderer/renderer_module.cc
+++ b/src/cobalt/renderer/renderer_module.cc
@@ -62,7 +62,8 @@
pipeline_ = make_scoped_ptr(new renderer::Pipeline(
base::Bind(options.create_rasterizer_function, graphics_context_.get(),
options),
- display_->GetRenderTarget(), graphics_context_.get()));
+ display_->GetRenderTarget(), graphics_context_.get(),
+ options.submit_even_if_render_tree_is_unchanged));
}
}
diff --git a/src/cobalt/renderer/renderer_module.h b/src/cobalt/renderer/renderer_module.h
index f60a29d..fab4b63 100644
--- a/src/cobalt/renderer/renderer_module.h
+++ b/src/cobalt/renderer/renderer_module.h
@@ -60,6 +60,12 @@
// nodes that are most CPU-expensive to render into surfaces.
int surface_cache_size_in_bytes;
+ // If this flag is set to true, the pipeline will not re-submit a render
+ // tree if it has not changed from the previous submission. This can save
+ // CPU time so long as there's no problem with the fact that the display
+ // buffer will not be frequently swapped.
+ bool submit_even_if_render_tree_is_unchanged;
+
private:
// Implemented per-platform, and allows each platform to customize
// the renderer options.
diff --git a/src/cobalt/renderer/renderer_module_default_options_starboard.cc b/src/cobalt/renderer/renderer_module_default_options_starboard.cc
index db5086b..7a00bd5 100644
--- a/src/cobalt/renderer/renderer_module_default_options_starboard.cc
+++ b/src/cobalt/renderer/renderer_module_default_options_starboard.cc
@@ -71,6 +71,12 @@
scratch_surface_cache_size_in_bytes =
COBALT_SCRATCH_SURFACE_CACHE_SIZE_IN_BYTES;
+ // If there is no need to frequently flip the display buffer, then enable
+ // support for an optimization where the scene is not re-rasterized each frame
+ // if it has not changed from the last frame.
+ submit_even_if_render_tree_is_unchanged =
+ SB_MUST_FREQUENTLY_FLIP_DISPLAY_BUFFER;
+
create_rasterizer_function = base::Bind(&CreateRasterizer);
}
diff --git a/src/cobalt/renderer/renderer_module_default_options_win.cc b/src/cobalt/renderer/renderer_module_default_options_win.cc
index 6b08fc9..b96c5f0 100644
--- a/src/cobalt/renderer/renderer_module_default_options_win.cc
+++ b/src/cobalt/renderer/renderer_module_default_options_win.cc
@@ -47,6 +47,8 @@
scratch_surface_cache_size_in_bytes =
COBALT_SCRATCH_SURFACE_CACHE_SIZE_IN_BYTES;
+ submit_even_if_render_tree_is_unchanged = true;
+
create_rasterizer_function = base::Bind(&CreateRasterizer);
}
diff --git a/src/cobalt/script/mozjs/conversion_helpers.h b/src/cobalt/script/mozjs/conversion_helpers.h
index 19a8ec8..6166bfa 100644
--- a/src/cobalt/script/mozjs/conversion_helpers.h
+++ b/src/cobalt/script/mozjs/conversion_helpers.h
@@ -368,6 +368,10 @@
context,
global_environment->wrapper_factory()->GetWrapperProxy(in_object));
DCHECK(object);
+ JS::RootedObject proxy_target(context, js::GetProxyTargetObject(object));
+ if (JS_IsGlobalObject(proxy_target)) {
+ object = proxy_target;
+ }
out_value.set(OBJECT_TO_JSVAL(object));
}
diff --git a/src/cobalt/script/mozjs/mozjs_callback_function.h b/src/cobalt/script/mozjs/mozjs_callback_function.h
index a2714de..cb3abc6 100644
--- a/src/cobalt/script/mozjs/mozjs_callback_function.h
+++ b/src/cobalt/script/mozjs/mozjs_callback_function.h
@@ -58,12 +58,12 @@
CallbackResult<R> Run()
const OVERRIDE {
CallbackResult<R> callback_result;
+ JSAutoRequest auto_request(context_);
JS::RootedObject function(context_, weak_function_.Get());
if (!function) {
DLOG(WARNING) << "Function was garbage collected.";
callback_result.exception = true;
} else {
- JSAutoRequest auto_request(context_);
JSAutoCompartment auto_compartment(context_, function);
JSExceptionState* previous_exception_state =
JS_SaveExceptionState(context_);
@@ -111,12 +111,12 @@
typename base::internal::CallbackParamTraits<A1>::ForwardType a1)
const OVERRIDE {
CallbackResult<R> callback_result;
+ JSAutoRequest auto_request(context_);
JS::RootedObject function(context_, weak_function_.Get());
if (!function) {
DLOG(WARNING) << "Function was garbage collected.";
callback_result.exception = true;
} else {
- JSAutoRequest auto_request(context_);
JSAutoCompartment auto_compartment(context_, function);
JSExceptionState* previous_exception_state =
JS_SaveExceptionState(context_);
@@ -170,12 +170,12 @@
typename base::internal::CallbackParamTraits<A2>::ForwardType a2)
const OVERRIDE {
CallbackResult<R> callback_result;
+ JSAutoRequest auto_request(context_);
JS::RootedObject function(context_, weak_function_.Get());
if (!function) {
DLOG(WARNING) << "Function was garbage collected.";
callback_result.exception = true;
} else {
- JSAutoRequest auto_request(context_);
JSAutoCompartment auto_compartment(context_, function);
JSExceptionState* previous_exception_state =
JS_SaveExceptionState(context_);
@@ -231,12 +231,12 @@
typename base::internal::CallbackParamTraits<A3>::ForwardType a3)
const OVERRIDE {
CallbackResult<R> callback_result;
+ JSAutoRequest auto_request(context_);
JS::RootedObject function(context_, weak_function_.Get());
if (!function) {
DLOG(WARNING) << "Function was garbage collected.";
callback_result.exception = true;
} else {
- JSAutoRequest auto_request(context_);
JSAutoCompartment auto_compartment(context_, function);
JSExceptionState* previous_exception_state =
JS_SaveExceptionState(context_);
@@ -294,12 +294,12 @@
typename base::internal::CallbackParamTraits<A4>::ForwardType a4)
const OVERRIDE {
CallbackResult<R> callback_result;
+ JSAutoRequest auto_request(context_);
JS::RootedObject function(context_, weak_function_.Get());
if (!function) {
DLOG(WARNING) << "Function was garbage collected.";
callback_result.exception = true;
} else {
- JSAutoRequest auto_request(context_);
JSAutoCompartment auto_compartment(context_, function);
JSExceptionState* previous_exception_state =
JS_SaveExceptionState(context_);
@@ -360,12 +360,12 @@
typename base::internal::CallbackParamTraits<A5>::ForwardType a5)
const OVERRIDE {
CallbackResult<R> callback_result;
+ JSAutoRequest auto_request(context_);
JS::RootedObject function(context_, weak_function_.Get());
if (!function) {
DLOG(WARNING) << "Function was garbage collected.";
callback_result.exception = true;
} else {
- JSAutoRequest auto_request(context_);
JSAutoCompartment auto_compartment(context_, function);
JSExceptionState* previous_exception_state =
JS_SaveExceptionState(context_);
@@ -428,12 +428,12 @@
typename base::internal::CallbackParamTraits<A6>::ForwardType a6)
const OVERRIDE {
CallbackResult<R> callback_result;
+ JSAutoRequest auto_request(context_);
JS::RootedObject function(context_, weak_function_.Get());
if (!function) {
DLOG(WARNING) << "Function was garbage collected.";
callback_result.exception = true;
} else {
- JSAutoRequest auto_request(context_);
JSAutoCompartment auto_compartment(context_, function);
JSExceptionState* previous_exception_state =
JS_SaveExceptionState(context_);
@@ -498,12 +498,12 @@
typename base::internal::CallbackParamTraits<A7>::ForwardType a7)
const OVERRIDE {
CallbackResult<R> callback_result;
+ JSAutoRequest auto_request(context_);
JS::RootedObject function(context_, weak_function_.Get());
if (!function) {
DLOG(WARNING) << "Function was garbage collected.";
callback_result.exception = true;
} else {
- JSAutoRequest auto_request(context_);
JSAutoCompartment auto_compartment(context_, function);
JSExceptionState* previous_exception_state =
JS_SaveExceptionState(context_);
diff --git a/src/cobalt/script/mozjs/mozjs_callback_function.h.pump b/src/cobalt/script/mozjs/mozjs_callback_function.h.pump
index 810dcc5..14067e9 100644
--- a/src/cobalt/script/mozjs/mozjs_callback_function.h.pump
+++ b/src/cobalt/script/mozjs/mozjs_callback_function.h.pump
@@ -77,12 +77,12 @@
typename base::internal::CallbackParamTraits<A$(ARG)>::ForwardType a$(ARG)]])
const OVERRIDE {
CallbackResult<R> callback_result;
+ JSAutoRequest auto_request(context_);
JS::RootedObject function(context_, weak_function_.Get());
if (!function) {
DLOG(WARNING) << "Function was garbage collected.";
callback_result.exception = true;
} else {
- JSAutoRequest auto_request(context_);
JSAutoCompartment auto_compartment(context_, function);
JSExceptionState* previous_exception_state =
JS_SaveExceptionState(context_);
diff --git a/src/cobalt/script/mozjs/mozjs_user_object_holder.h b/src/cobalt/script/mozjs/mozjs_user_object_holder.h
index 2ee384f..c70ad1a 100644
--- a/src/cobalt/script/mozjs/mozjs_user_object_holder.h
+++ b/src/cobalt/script/mozjs/mozjs_user_object_holder.h
@@ -51,6 +51,7 @@
wrapper_factory_(wrapper_factory) {}
void RegisterOwner(Wrappable* owner) OVERRIDE {
+ JSAutoRequest auto_request(context_);
JS::RootedObject owned_object(context_, js_object());
DLOG_IF(WARNING, !owned_object)
<< "Owned object has been garbage collected.";
@@ -65,6 +66,7 @@
void DeregisterOwner(Wrappable* owner) OVERRIDE {
// |owner| may be in the process of being destructed, so don't use it.
+ JSAutoRequest auto_request(context_);
JS::RootedObject owned_object(context_, js_object());
if (owned_object) {
MozjsGlobalEnvironment* global_environment =
@@ -82,6 +84,7 @@
scoped_ptr<BaseClass> MakeCopy() const OVERRIDE {
DCHECK(object_handle_);
+ JSAutoRequest auto_request(context_);
JS::RootedObject rooted_object(context_, js_object());
return make_scoped_ptr<BaseClass>(
new MozjsUserObjectHolder(rooted_object, context_, wrapper_factory_));
diff --git a/src/cobalt/script/mozjs/opaque_root_tracker.cc b/src/cobalt/script/mozjs/opaque_root_tracker.cc
index 1ae8d32..dfc405e 100644
--- a/src/cobalt/script/mozjs/opaque_root_tracker.cc
+++ b/src/cobalt/script/mozjs/opaque_root_tracker.cc
@@ -20,6 +20,7 @@
#include <vector>
#include "cobalt/script/mozjs/weak_heap_object.h"
+#include "third_party/mozjs/js/src/jsapi.h"
namespace cobalt {
namespace script {
@@ -45,6 +46,7 @@
}
~OpaqueRootStateImpl() {
+ JSAutoRequest auto_request(context_);
for (ReferencedObjectPairVector::iterator it = referenced_objects_.begin();
it != referenced_objects_.end(); ++it) {
if (it->second.Get()) {
diff --git a/src/cobalt/script/mozjs/util/exception_helpers.cc b/src/cobalt/script/mozjs/util/exception_helpers.cc
index 030f45a..ce0ca06 100644
--- a/src/cobalt/script/mozjs/util/exception_helpers.cc
+++ b/src/cobalt/script/mozjs/util/exception_helpers.cc
@@ -20,6 +20,7 @@
#include "cobalt/script/mozjs/conversion_helpers.h"
#include "cobalt/script/mozjs/mozjs_exception_state.h"
+#include "third_party/mozjs/js/src/jsapi.h"
#include "third_party/mozjs/js/src/jsdbgapi.h"
#include "third_party/mozjs/js/src/jsscript.h"
@@ -28,6 +29,7 @@
namespace mozjs {
namespace util {
std::vector<StackFrame> GetStackTrace(JSContext* context, int max_frames) {
+ JSAutoRequest auto_request(context);
JS::StackDescription* stack_description =
JS::DescribeStack(context, max_frames);
if (max_frames == 0) {
diff --git a/src/cobalt/storage/storage.gyp b/src/cobalt/storage/storage.gyp
index 599f95a..ca9bc16 100644
--- a/src/cobalt/storage/storage.gyp
+++ b/src/cobalt/storage/storage.gyp
@@ -32,13 +32,17 @@
'savegame_fake.cc',
'storage_manager.cc',
'storage_manager.h',
+ 'upgrade/upgrade_reader.cc',
+ 'upgrade/upgrade_reader.h',
'virtual_file.cc',
'virtual_file.h',
'virtual_file_system.cc',
'virtual_file_system.h',
],
'dependencies': [
+ '<(DEPTH)/base/base.gyp:base',
'<(DEPTH)/cobalt/base/base.gyp:base',
+ '<(DEPTH)/net/net.gyp:net',
'<(DEPTH)/sql/sql.gyp:sql',
],
'conditions': [
@@ -70,6 +74,7 @@
'sources': [
'savegame_test.cc',
'storage_manager_test.cc',
+ 'upgrade/storage_upgrade_test.cc',
'virtual_file_system_test.cc',
],
'dependencies': [
@@ -78,6 +83,7 @@
'<(DEPTH)/testing/gmock.gyp:gmock',
'<(DEPTH)/testing/gtest.gyp:gtest',
'storage',
+ 'storage_upgrade_copy_test_data',
],
},
{
@@ -91,5 +97,21 @@
},
'includes': [ '../../starboard/build/deploy.gypi' ],
},
+ {
+ 'target_name': 'storage_upgrade_copy_test_data',
+ 'type': 'none',
+ 'actions': [
+ {
+ 'action_name': 'storage_upgrade_copy_test_data',
+ 'variables': {
+ 'input_files': [
+ '<(DEPTH)/cobalt/storage/upgrade/testdata/',
+ ],
+ 'output_dir': 'cobalt/storage/upgrade/testdata/',
+ },
+ 'includes': [ '../build/copy_test_data.gypi' ],
+ },
+ ],
+ },
],
}
diff --git a/src/cobalt/storage/upgrade/schema_v1.proto b/src/cobalt/storage/upgrade/schema_v1.proto
new file mode 100644
index 0000000..6907806
--- /dev/null
+++ b/src/cobalt/storage/upgrade/schema_v1.proto
@@ -0,0 +1,83 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// File schema for "upgrade" save data.
+//
+// A platform migrating to Cobalt from a pre-existing HTML5 container may need
+// to load save data in the legacy format into Cobalt. In this case, it is
+// expected the platform implementation will return the legacy save data in the
+// format described by this schema (JSON-encoded data prefixed by a fixed
+// identifier), which will then be detected by Cobalt and upgraded to the
+// current save data format.
+
+// The first 4 bytes of the data must be the ASCII characters: "UPG0".
+// The remainder of the data must be JSON-encoded according to the schema below.
+// For details of how the proto3 syntax used here maps to JSON, see:
+// https://developers.google.com/protocol-buffers/docs/proto3#json
+
+syntax = "proto3";
+
+message SaveData {
+ // Array (possibly empty) of Cookie objects, defined below.
+ repeated Cookie cookies = 1;
+
+ // Array (possibly empty) of LocalStorageEntry objects, defined below.
+ repeated LocalStorageEntry local_storage_entries = 2;
+
+ // A single cookie.
+ mesage Cookie {
+ // URL in canonical form, e.g. "https://www.youtube.com/". Must be provided
+ // or the cookie will be ignored.
+ string url = 1;
+
+ // Application-defined key. Must be provided or the cookie will be ignored.
+ string name = 2;
+
+ // Application-defined value, treated opaquely by Cobalt. Must be provided
+ // or the cookie will be ignored.
+ string value = 3;
+
+ // Domain, e.g. ".youtube.com". Defaults to the domain of the "url" field.
+ string domain = 4;
+
+ // Optional virtual path, defaults to "/".
+ string path = 5;
+
+ // Microseconds since Windows epoch (1601-01-01 00:00:00 UTC), as ASCII
+ // decimal string. Defaults to now.
+ int64 creation = 6;
+
+ // Microseconds since Windows epoch (1601-01-01 00:00:00 UTC), as ASCII
+ // decimal string. Defaults to maximum expiration period from now.
+ int64 expiration = 7;
+
+ // Microseconds since Windows epoch (1601-01-01 00:00:00 UTC), as ASCII
+ // decimal string. Defaults to now.
+ int64 last_access = 8;
+
+ // Whether this is an HTTP-only cookie. Defaults to false.
+ bool http_only = 9;
+ }
+
+ // A single local storage entry.
+ message LocalStorageEntry {
+ // Application-defined key. Must be provided or the local storage entry will
+ // be ignored.
+ string key = 1;
+
+ // Application-defined value, treated opaquely by Cobalt. Must be provided
+ // or the local storage entry will be ignored.
+ string value = 2;
+ }
+}
diff --git a/src/cobalt/storage/upgrade/storage_upgrade_test.cc b/src/cobalt/storage/upgrade/storage_upgrade_test.cc
new file mode 100644
index 0000000..e7b64f0
--- /dev/null
+++ b/src/cobalt/storage/upgrade/storage_upgrade_test.cc
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstring>
+
+#include "base/base_paths.h"
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/path_service.h"
+#include "base/platform_file.h"
+#include "base/time.h"
+#include "cobalt/storage/upgrade/upgrade_reader.h"
+#include "googleurl/src/gurl.h"
+#include "net/cookies/canonical_cookie.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cobalt {
+namespace storage {
+namespace upgrade {
+
+namespace {
+
+const int kHeaderSize = 4;
+const char kHeader[] = "UPG0";
+
+void ReadFileToString(const char* pathname, std::string* string_out) {
+ EXPECT_TRUE(pathname);
+ EXPECT_TRUE(string_out);
+ FilePath file_path;
+ EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &file_path));
+ file_path = file_path.Append(pathname);
+ EXPECT_TRUE(file_util::ReadFileToString(file_path, string_out));
+ EXPECT_GT(string_out->length(), static_cast<size_t>(kHeaderSize));
+ EXPECT_LE(string_out->length(), static_cast<size_t>(10 * 1024 * 1024));
+ EXPECT_EQ(string_out->find(kHeader), 0);
+}
+
+void ValidateCookie(const net::CanonicalCookie* cookie, const std::string& url,
+ const std::string& name, const std::string& value,
+ const std::string domain, const std::string& path,
+ const base::Time& creation, const base::Time expiration,
+ bool http_only) {
+ EXPECT_TRUE(cookie);
+ EXPECT_EQ(cookie->Source(),
+ net::CanonicalCookie::GetCookieSourceFromURL(GURL(url)));
+ EXPECT_EQ(cookie->Name(), name);
+ EXPECT_EQ(cookie->Value(), value);
+ EXPECT_EQ(cookie->Domain(), domain);
+ EXPECT_EQ(cookie->Path(), path);
+ EXPECT_EQ((cookie->CreationDate() - creation).InSeconds(), 0);
+ EXPECT_EQ((cookie->ExpiryDate() - expiration).InSeconds(), 0);
+ EXPECT_EQ((cookie->LastAccessDate() - base::Time::Now()).InSeconds(), 0);
+ EXPECT_EQ(cookie->IsSecure(), true);
+ EXPECT_EQ(cookie->IsHttpOnly(), http_only);
+}
+
+void ValidateCookie(const net::CanonicalCookie* cookie, const std::string& url,
+ const std::string& name, const std::string& value) {
+ const std::string host = GURL(url).host();
+ const std::string domain = host.empty() ? "" : host.substr(host.find("."));
+ const std::string path = "/";
+ const base::Time creation = base::Time::Now();
+ const base::Time expiration = creation;
+ const bool http_only = false;
+ ValidateCookie(cookie, url, name, value, domain, path, creation, expiration,
+ http_only);
+}
+
+void ValidateLocalStorageEntry(
+ const UpgradeReader::LocalStorageEntry* local_storage_entry,
+ const std::string& key, const std::string& value) {
+ EXPECT_TRUE(local_storage_entry);
+ EXPECT_EQ(local_storage_entry->key, key);
+ EXPECT_EQ(local_storage_entry->value, value);
+}
+
+} // namespace
+
+TEST(StorageUpgradeTest, UpgradeMinimalCookie) {
+ std::string file_contents;
+ ReadFileToString("cobalt/storage/upgrade/testdata/minimal_cookie_v1.json",
+ &file_contents);
+ UpgradeReader upgrade_reader(
+ file_contents.c_str() + kHeaderSize,
+ static_cast<int>(file_contents.length()) - kHeaderSize);
+
+ // 1 cookie.
+ EXPECT_EQ(upgrade_reader.GetNumCookies(), 1);
+ const net::CanonicalCookie* cookie = upgrade_reader.GetCookie(0);
+ ValidateCookie(cookie, "https://www.youtube.com/", "cookie_name",
+ "cookie_value");
+ EXPECT_FALSE(upgrade_reader.GetCookie(1));
+
+ // 0 local storage entries.
+ EXPECT_EQ(upgrade_reader.GetNumLocalStorageEntries(), 0);
+ EXPECT_FALSE(upgrade_reader.GetLocalStorageEntry(0));
+}
+
+TEST(StorageUpgradeTest, UpgradeMinimalLocalStorageEntry) {
+ std::string file_contents;
+ ReadFileToString(
+ "cobalt/storage/upgrade/testdata/minimal_local_storage_entry_v1.json",
+ &file_contents);
+ UpgradeReader upgrade_reader(
+ file_contents.c_str() + kHeaderSize,
+ static_cast<int>(file_contents.length()) - kHeaderSize);
+
+ // 0 cookies.
+ EXPECT_EQ(upgrade_reader.GetNumCookies(), 0);
+ EXPECT_FALSE(upgrade_reader.GetCookie(0));
+
+ // 1 local storage entry.
+ EXPECT_EQ(upgrade_reader.GetNumLocalStorageEntries(), 1);
+ const UpgradeReader::LocalStorageEntry* local_storage_entry =
+ upgrade_reader.GetLocalStorageEntry(0);
+ ValidateLocalStorageEntry(local_storage_entry, "key-1", "value-1");
+ EXPECT_FALSE(upgrade_reader.GetLocalStorageEntry(1));
+}
+
+TEST(StorageUpgradeTest, UpgradeFullData) {
+ std::string file_contents;
+ ReadFileToString("cobalt/storage/upgrade/testdata/full_data_v1.json",
+ &file_contents);
+ UpgradeReader upgrade_reader(
+ file_contents.c_str() + kHeaderSize,
+ static_cast<int>(file_contents.length()) - kHeaderSize);
+
+ // 2 cookies.
+ EXPECT_EQ(upgrade_reader.GetNumCookies(), 2);
+ const net::CanonicalCookie* cookie = upgrade_reader.GetCookie(0);
+ base::Time creation = base::Time::FromInternalValue(13119668760000000L);
+ base::Time expiration = base::Time::FromInternalValue(13120000000000000L);
+ ValidateCookie(cookie, "https://www.youtube.com/", "cookie_name",
+ "cookie_value", "cookie.domain", "cookie/path", creation,
+ expiration, true);
+ cookie = upgrade_reader.GetCookie(1);
+ creation = base::Time::FromInternalValue(13109668760000000L);
+ expiration = base::Time::FromInternalValue(13110000000000000L);
+ ValidateCookie(cookie, "https://www.somewhere.com/", "cookie_name_2",
+ "cookie_value_2", "cookie.domain2", "cookie/path/2", creation,
+ expiration, true);
+ EXPECT_FALSE(upgrade_reader.GetCookie(2));
+
+ // 2 local storage entries.
+ EXPECT_EQ(upgrade_reader.GetNumLocalStorageEntries(), 2);
+ const UpgradeReader::LocalStorageEntry* local_storage_entry =
+ upgrade_reader.GetLocalStorageEntry(0);
+ ValidateLocalStorageEntry(local_storage_entry, "key-1", "value-1");
+ local_storage_entry = upgrade_reader.GetLocalStorageEntry(1);
+ ValidateLocalStorageEntry(local_storage_entry, "key-2", "value-2");
+ EXPECT_FALSE(upgrade_reader.GetLocalStorageEntry(2));
+}
+
+TEST(StorageUpgradeTest, UpgradeMissingFields) {
+ std::string file_contents;
+ ReadFileToString("cobalt/storage/upgrade/testdata/missing_fields_v1.json",
+ &file_contents);
+ UpgradeReader upgrade_reader(
+ file_contents.c_str() + kHeaderSize,
+ static_cast<int>(file_contents.length()) - kHeaderSize);
+
+ // 1 cookie with missing fields, 2 local storage entries with missing fields,
+ // 1 valid local storage entry.
+ EXPECT_EQ(upgrade_reader.GetNumCookies(), 0);
+ EXPECT_FALSE(upgrade_reader.GetCookie(0));
+ EXPECT_EQ(upgrade_reader.GetNumLocalStorageEntries(), 1);
+ const UpgradeReader::LocalStorageEntry* local_storage_entry =
+ upgrade_reader.GetLocalStorageEntry(0);
+ ValidateLocalStorageEntry(local_storage_entry, "key-3", "value-3");
+ EXPECT_FALSE(upgrade_reader.GetLocalStorageEntry(1));
+}
+
+TEST(StorageUpgradeTest, UpgradeMalformed) {
+ std::string file_contents;
+ ReadFileToString("cobalt/storage/upgrade/testdata/malformed_v1.json",
+ &file_contents);
+ UpgradeReader upgrade_reader(
+ file_contents.c_str() + kHeaderSize,
+ static_cast<int>(file_contents.length()) - kHeaderSize);
+
+ // No cookies or local storage entries available in malformed data.
+ EXPECT_EQ(upgrade_reader.GetNumCookies(), 0);
+ EXPECT_FALSE(upgrade_reader.GetCookie(0));
+ EXPECT_EQ(upgrade_reader.GetNumLocalStorageEntries(), 0);
+ EXPECT_FALSE(upgrade_reader.GetLocalStorageEntry(0));
+}
+
+TEST(StorageUpgradeTest, UpgradeExtraFields) {
+ std::string file_contents;
+ ReadFileToString("cobalt/storage/upgrade/testdata/extra_fields_v1.json",
+ &file_contents);
+ UpgradeReader upgrade_reader(
+ file_contents.c_str() + kHeaderSize,
+ static_cast<int>(file_contents.length()) - kHeaderSize);
+
+ // 1 cookie, extra fields should be ignored.
+ EXPECT_EQ(upgrade_reader.GetNumCookies(), 1);
+ const net::CanonicalCookie* cookie = upgrade_reader.GetCookie(0);
+ ValidateCookie(cookie, "https://www.youtube.com/", "cookie_name",
+ "cookie_value");
+ EXPECT_FALSE(upgrade_reader.GetCookie(1));
+
+ // 2 local storage entries, extra fields should be ignored.
+ EXPECT_EQ(upgrade_reader.GetNumLocalStorageEntries(), 2);
+ const UpgradeReader::LocalStorageEntry* local_storage_entry =
+ upgrade_reader.GetLocalStorageEntry(0);
+ ValidateLocalStorageEntry(local_storage_entry, "key-1", "value-1");
+ local_storage_entry = upgrade_reader.GetLocalStorageEntry(1);
+ ValidateLocalStorageEntry(local_storage_entry, "key-2", "value-2");
+ EXPECT_FALSE(upgrade_reader.GetLocalStorageEntry(2));
+}
+
+} // namespace upgrade
+} // namespace storage
+} // namespace cobalt
diff --git a/src/cobalt/storage/upgrade/testdata/extra_fields_v1.json b/src/cobalt/storage/upgrade/testdata/extra_fields_v1.json
new file mode 100644
index 0000000..7709e50
--- /dev/null
+++ b/src/cobalt/storage/upgrade/testdata/extra_fields_v1.json
@@ -0,0 +1,22 @@
+UPG0
+{
+ "cookies": [
+ {
+ "url": "https://www.youtube.com",
+ "name": "cookie_name",
+ "value": "cookie_value",
+ "unexpected": "dummy_value"
+ }
+ ],
+ "local_storage_entries": [
+ {
+ "key": "key-1",
+ "value": "value-1",
+ "unexpected": "dummy_value"
+ },
+ {
+ "key": "key-2",
+ "value": "value-2"
+ }
+ ]
+}
diff --git a/src/cobalt/storage/upgrade/testdata/full_data_v1.json b/src/cobalt/storage/upgrade/testdata/full_data_v1.json
new file mode 100644
index 0000000..c5a039f
--- /dev/null
+++ b/src/cobalt/storage/upgrade/testdata/full_data_v1.json
@@ -0,0 +1,37 @@
+UPG0
+{
+ "cookies": [
+ {
+ "url": "https://www.youtube.com",
+ "name": "cookie_name",
+ "value": "cookie_value",
+ "domain": "cookie.domain",
+ "path": "cookie/path",
+ "creation": "13119668760000000",
+ "expiration": "13120000000000000",
+ "last_acess": "13119668770000000",
+ "http_only": true
+ },
+ {
+ "url": "http://www.somewhere.com",
+ "name": "cookie_name_2",
+ "value": "cookie_value_2",
+ "domain": "cookie.domain2",
+ "path": "cookie/path/2",
+ "creation": "13109668760000000",
+ "expiration": "13110000000000000",
+ "last_acess": "13109668770000000",
+ "http_only": true
+ }
+ ],
+ "local_storage_entries": [
+ {
+ "key": "key-1",
+ "value": "value-1"
+ },
+ {
+ "key": "key-2",
+ "value": "value-2"
+ }
+ ]
+}
diff --git a/src/cobalt/storage/upgrade/testdata/malformed_v1.json b/src/cobalt/storage/upgrade/testdata/malformed_v1.json
new file mode 100644
index 0000000..6d87bf0
--- /dev/null
+++ b/src/cobalt/storage/upgrade/testdata/malformed_v1.json
@@ -0,0 +1,36 @@
+UPG0
+{
+ "cookies": [
+ {
+ "url": "https://www.youtube.com",
+ "name": "cookie_name",
+ "value": "cookie_value"
+ "domain": "cookie.domain",
+ "path": "cookie/path",
+ "creation": "13119668760000000",
+ "expiration": "13120000000000000",
+ "last_acess": "13119668770000000",
+ "http_only": true
+ },
+ {
+ "url": "http://www.somewhere.com",
+ "name": "cookie_name_2",
+ "value": "cookie_value_2",
+ "domain": "cookie.domain2",
+ "path": "cookie/path/2",
+ "creation": "13109668760000000",
+ "expiration": "13110000000000000",
+ "last_acess": "13109668770000000",
+ "http_only": true
+ ],
+ "local_storage_entries":
+ {
+ "key": "key-1",
+ "value": "value-1"
+ },
+ {
+ "key": "key-2",
+ "value": "value-2"
+ }
+ ]
+}
diff --git a/src/cobalt/storage/upgrade/testdata/minimal_cookie_v1.json b/src/cobalt/storage/upgrade/testdata/minimal_cookie_v1.json
new file mode 100644
index 0000000..7dbd209
--- /dev/null
+++ b/src/cobalt/storage/upgrade/testdata/minimal_cookie_v1.json
@@ -0,0 +1,10 @@
+UPG0
+{
+ "cookies": [
+ {
+ "url": "https://www.youtube.com",
+ "name": "cookie_name",
+ "value": "cookie_value"
+ }
+ ]
+}
diff --git a/src/cobalt/storage/upgrade/testdata/minimal_local_storage_entry_v1.json b/src/cobalt/storage/upgrade/testdata/minimal_local_storage_entry_v1.json
new file mode 100644
index 0000000..555e62d
--- /dev/null
+++ b/src/cobalt/storage/upgrade/testdata/minimal_local_storage_entry_v1.json
@@ -0,0 +1,9 @@
+UPG0
+{
+ "local_storage_entries": [
+ {
+ "key": "key-1",
+ "value": "value-1"
+ }
+ ]
+}
diff --git a/src/cobalt/storage/upgrade/testdata/missing_fields_v1.json b/src/cobalt/storage/upgrade/testdata/missing_fields_v1.json
new file mode 100644
index 0000000..52a2a4e
--- /dev/null
+++ b/src/cobalt/storage/upgrade/testdata/missing_fields_v1.json
@@ -0,0 +1,21 @@
+UPG0
+{
+ "cookies": [
+ {
+ "name": "cookie_name",
+ "value": "cookie_value"
+ }
+ ],
+ "local_storage_entries": [
+ {
+ "key": "key-1"
+ },
+ {
+ "value": "value-2"
+ },
+ {
+ "key": "key-3",
+ "value": "value-3"
+ }
+ ]
+}
diff --git a/src/cobalt/storage/upgrade/upgrade_reader.cc b/src/cobalt/storage/upgrade/upgrade_reader.cc
new file mode 100644
index 0000000..35fdb53
--- /dev/null
+++ b/src/cobalt/storage/upgrade/upgrade_reader.cc
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "cobalt/storage/upgrade/upgrade_reader.h"
+
+#include <string>
+
+#include "base/json/json_reader.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/string_number_conversions.h"
+#include "googleurl/src/gurl.h"
+
+namespace cobalt {
+namespace storage {
+namespace upgrade {
+
+namespace {
+
+// Used as a sanity check.
+const int kMaxUpgradeDataSize = 10 * 1024 * 1024;
+
+// Deseralize a time value encoded as a possibly empty ASCII decimal string.
+base::Time StringToTime(const std::string& time_as_string) {
+ if (!time_as_string.empty()) {
+ int64 time_as_int64;
+ if (base::StringToInt64(time_as_string, &time_as_int64)) {
+ return base::Time::FromInternalValue(time_as_int64);
+ }
+ }
+
+ // Default value.
+ return base::Time::Now();
+}
+
+base::Time GetSerializedTime(const base::DictionaryValue* dictionary,
+ const std::string& field_name) {
+ std::string time_string;
+ dictionary->GetString(field_name, &time_string);
+ return StringToTime(time_string);
+}
+
+// Get a list contained in a dictionary.
+const base::ListValue* GetList(const base::DictionaryValue* dictionary,
+ const std::string& list_name) {
+ if (!dictionary) {
+ return NULL;
+ }
+
+ const base::ListValue* list = NULL;
+ if (!dictionary->GetList(list_name, &list)) {
+ return NULL;
+ }
+
+ return list;
+}
+
+// Get the size of a list contained in a dictionary.
+int GetListSize(const base::DictionaryValue* dictionary,
+ const std::string& list_name) {
+ const base::ListValue* list = GetList(dictionary, list_name);
+ if (!list) {
+ return 0;
+ }
+
+ return static_cast<int>(list->GetSize());
+}
+
+// Get a dictionary in a list contained in a dictionary.
+const base::DictionaryValue* GetListItem(
+ const base::DictionaryValue* dictionary, const std::string& list_name,
+ int index) {
+ const base::ListValue* list = GetList(dictionary, list_name);
+ if (!list) {
+ return NULL;
+ }
+
+ if (index < 0 || index >= static_cast<int>(list->GetSize())) {
+ return NULL;
+ }
+
+ const base::DictionaryValue* list_item = NULL;
+ if (!list->GetDictionary(static_cast<size_t>(index), &list_item)) {
+ return NULL;
+ }
+
+ return list_item;
+}
+
+} // namespace
+
+UpgradeReader::UpgradeReader(const char* data, int size) {
+ DCHECK(data);
+ DCHECK_GT(size, 0);
+ DCHECK_LE(size, kMaxUpgradeDataSize);
+
+ base::JSONReader json_reader;
+ scoped_ptr<base::Value> parsed(
+ json_reader.ReadToValue(std::string(data, static_cast<size_t>(size))));
+ base::DictionaryValue* valid_dictionary = NULL;
+ if (parsed) {
+ parsed->GetAsDictionary(&valid_dictionary);
+ }
+
+ if (valid_dictionary) {
+ ProcessValues(valid_dictionary);
+ } else {
+ DLOG(ERROR) << "Cannot parse upgrade save data: "
+ << base::JSONReader::ErrorCodeToString(
+ json_reader.error_code());
+ }
+}
+
+int UpgradeReader::GetNumCookies() const {
+ return static_cast<int>(cookies_.size());
+}
+
+int UpgradeReader::GetNumLocalStorageEntries() const {
+ return static_cast<int>(local_storage_entries_.size());
+}
+
+const net::CanonicalCookie* UpgradeReader::GetCookie(int index) const {
+ if (index >= 0 && index < static_cast<int>(cookies_.size())) {
+ return &cookies_[static_cast<size_t>(index)];
+ } else {
+ return static_cast<const net::CanonicalCookie*>(NULL);
+ }
+}
+
+void UpgradeReader::AddCookieIfValid(const base::DictionaryValue* cookie) {
+ DCHECK(cookie);
+
+ // Required attributes.
+ std::string url;
+ std::string name;
+ std::string value;
+ cookie->GetString("url", &url);
+ cookie->GetString("name", &name);
+ cookie->GetString("value", &value);
+ if (url.empty() || name.empty() || value.empty()) {
+ return;
+ }
+
+ // Optional attributes with default values.
+ const GURL gurl(url);
+ const std::string host = gurl.host();
+ std::string domain = host.empty() ? "" : host.substr(host.find("."));
+ cookie->GetString("domain", &domain);
+ std::string path = "/";
+ cookie->GetString("path", &path);
+ base::Time creation = GetSerializedTime(cookie, "creation");
+ base::Time expiration = GetSerializedTime(cookie, "expiration");
+ base::Time last_access = GetSerializedTime(cookie, "last_access");
+ bool http_only = false;
+ cookie->GetBoolean("http_only", &http_only);
+
+ // Attributes not defined in upgrade data.
+ const std::string mac_key;
+ const std::string mac_algorithm;
+ const bool secure = true;
+
+ cookies_.push_back(net::CanonicalCookie(
+ gurl, name, value, domain, path, mac_key, mac_algorithm, creation,
+ expiration, last_access, secure, http_only));
+}
+
+const UpgradeReader::LocalStorageEntry* UpgradeReader::GetLocalStorageEntry(
+ int index) const {
+ if (index >= 0 && index < static_cast<int>(local_storage_entries_.size())) {
+ return &local_storage_entries_[static_cast<size_t>(index)];
+ } else {
+ return static_cast<const LocalStorageEntry*>(NULL);
+ }
+}
+
+void UpgradeReader::AddLocalStorageEntryIfValid(
+ const base::DictionaryValue* local_storage_entry) {
+ DCHECK(local_storage_entry);
+ std::string key;
+ std::string value;
+ if (!local_storage_entry->GetString("key", &key) ||
+ !local_storage_entry->GetString("value", &value) || key.empty() ||
+ value.empty()) {
+ return;
+ }
+
+ local_storage_entries_.push_back(LocalStorageEntry(key, value));
+}
+
+void UpgradeReader::ProcessValues(const base::DictionaryValue* dictionary) {
+ DCHECK(dictionary);
+
+ const int num_cookies = GetListSize(dictionary, "cookies");
+ for (int n = 0; n < num_cookies; n++) {
+ const base::DictionaryValue* cookie = GetListItem(dictionary, "cookies", n);
+ if (cookie) {
+ AddCookieIfValid(cookie);
+ }
+ }
+
+ const int num_local_storage_entries =
+ GetListSize(dictionary, "local_storage_entries");
+ for (int n = 0; n < num_local_storage_entries; n++) {
+ const base::DictionaryValue* local_storage_entry =
+ GetListItem(dictionary, "local_storage_entries", n);
+ if (local_storage_entry) {
+ AddLocalStorageEntryIfValid(local_storage_entry);
+ }
+ }
+}
+
+} // namespace upgrade
+} // namespace storage
+} // namespace cobalt
diff --git a/src/cobalt/storage/upgrade/upgrade_reader.h b/src/cobalt/storage/upgrade/upgrade_reader.h
new file mode 100644
index 0000000..00d1462
--- /dev/null
+++ b/src/cobalt/storage/upgrade/upgrade_reader.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef COBALT_STORAGE_UPGRADE_UPGRADE_READER_H_
+#define COBALT_STORAGE_UPGRADE_UPGRADE_READER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/values.h"
+#include "net/cookies/canonical_cookie.h"
+
+namespace cobalt {
+namespace storage {
+namespace upgrade {
+
+// Class description goes here.
+class UpgradeReader {
+ public:
+ struct LocalStorageEntry {
+ LocalStorageEntry(const std::string& key, const std::string& value)
+ : key(key), value(value) {}
+ std::string key;
+ std::string value;
+ };
+
+ // Parse |data| in JSON-encoded legacy save data upgrade format.
+ UpgradeReader(const char* data, int size);
+
+ // The number of valid cookies found in the parsed data. May be zero.
+ int GetNumCookies() const;
+
+ // The number of valid local storage entries found in the parsed data. May be
+ // zero.
+ int GetNumLocalStorageEntries() const;
+
+ // Get one of the cookies found in the parsed data, specified by |index|
+ // between 0 and |GetNumCookies| - 1. If the cookie doesn't exist, return
+ // NULL.
+ const net::CanonicalCookie* GetCookie(int index) const;
+
+ // Get one of the local storage entries found in the parsed data, specified
+ // by |index| between 0 and |GetNumLocalStorageEntries| - 1. If the local
+ // storage entry doesn't exist, return NULL.
+ const LocalStorageEntry* GetLocalStorageEntry(int index) const;
+
+ private:
+ // Process the parsed values and populate |cookies_| and
+ // |local_storage_entries_|.
+ void ProcessValues(const base::DictionaryValue* dictionary);
+
+ // Add an entry to |cookies_| if |cookie| encodes a valid cookie.
+ void AddCookieIfValid(const base::DictionaryValue* cookie);
+
+ // Add an entry to |local_storage_entries_| if |local_storage_entry| encodes a
+ // valid local storage entry.
+ void AddLocalStorageEntryIfValid(
+ const base::DictionaryValue* local_storage_entry);
+
+ std::vector<net::CanonicalCookie> cookies_;
+ std::vector<LocalStorageEntry> local_storage_entries_;
+};
+
+} // namespace upgrade
+} // namespace storage
+} // namespace cobalt
+
+#endif // COBALT_STORAGE_UPGRADE_UPGRADE_READER_H_
diff --git a/src/cobalt/web_animations/animation.cc b/src/cobalt/web_animations/animation.cc
index 0c8a578..16c7d30 100644
--- a/src/cobalt/web_animations/animation.cc
+++ b/src/cobalt/web_animations/animation.cc
@@ -65,14 +65,18 @@
UpdatePendingTasks();
}
-// https://www.w3.org/TR/2015/WD-web-animations-1-20150707/#the-current-time-of-an-animation
-base::optional<double> Animation::current_time() const {
+base::optional<base::TimeDelta> Animation::current_time_as_time_delta() const {
if (!timeline_) {
return base::nullopt;
}
- base::optional<base::TimeDelta> current_time =
- data_.ComputeLocalTimeFromTimelineTime(timeline_->current_time());
+ return data_.ComputeLocalTimeFromTimelineTime(
+ timeline_->current_time_as_time_delta());
+}
+
+// https://www.w3.org/TR/2015/WD-web-animations-1-20150707/#the-current-time-of-an-animation
+base::optional<double> Animation::current_time() const {
+ base::optional<base::TimeDelta> current_time = current_time_as_time_delta();
return current_time ? base::optional<double>(current_time->InMillisecondsF())
: base::nullopt;
}
@@ -86,16 +90,27 @@
// https://www.w3.org/TR/2015/WD-web-animations-1-20150707/#the-current-time-of-an-animation
base::optional<base::TimeDelta>
Animation::Data::ComputeLocalTimeFromTimelineTime(
- const base::optional<double>& timeline_time_in_milliseconds) const {
+ const base::optional<base::TimeDelta>& timeline_time) const {
// TODO: Take into account the hold time.
- if (!timeline_time_in_milliseconds || !start_time_) {
+ if (!timeline_time || !start_time_) {
return base::nullopt;
}
- return ScaleTime(
- base::TimeDelta::FromMillisecondsD(*timeline_time_in_milliseconds) -
- *start_time_,
- playback_rate_);
+ return ScaleTime(*timeline_time - *start_time_, playback_rate_);
+}
+
+base::optional<base::TimeDelta>
+Animation::Data::ComputeTimelineTimeFromLocalTime(
+ const base::optional<base::TimeDelta>& local_time) const {
+ if (!start_time_ || !local_time) {
+ return base::nullopt;
+ }
+
+ if (local_time == base::TimeDelta::Max()) {
+ return base::TimeDelta::Max();
+ }
+
+ return ScaleTime(*local_time, 1.0 / playback_rate_) + *start_time_;
}
// https://www.w3.org/TR/2015/WD-web-animations-1-20150707/#setting-the-current-time-of-an-animation
@@ -116,35 +131,29 @@
}
void Animation::UpdatePendingTasks() {
- base::optional<double> local_time_in_ms = current_time();
+ if (!effect_) {
+ return;
+ }
- if (!local_time_in_ms) {
- // If the local time is unresolved, then we cannot know when we will enter
- // the "after phase".
- on_enter_after_phase_.reset();
+ base::TimeDelta end_time_local =
+ effect_->timing()->data().time_until_after_phase(base::TimeDelta());
+
+ base::optional<base::TimeDelta> end_time_timeline =
+ data_.ComputeTimelineTimeFromLocalTime(end_time_local);
+
+ // If the local time is unresolved, then we cannot know when we will enter
+ // the "after phase".
+ if (end_time_timeline &&
+ *end_time_timeline >= *timeline_->current_time_as_time_delta() &&
+ *end_time_timeline != base::TimeDelta::Max()) {
+ // Setup the "upon entering the after phase" event to fire at the
+ // specified timeline time.
+ on_enter_after_phase_ = timeline_->QueueTask(
+ *end_time_timeline,
+ base::Bind(&Animation::OnEnterAfterPhase, base::Unretained(this)));
} else {
- if (!effect_) {
- return;
- }
-
- base::TimeDelta local_time =
- base::TimeDelta::FromMillisecondsD(*local_time_in_ms);
-
- base::TimeDelta time_to_after_phase =
- effect_->timing()->data().time_until_after_phase(local_time);
- if (time_to_after_phase >= base::TimeDelta() &&
- time_to_after_phase != base::TimeDelta::Max()) {
- // Setup the "upon entering the after phase" event to fire at the
- // specified timeline time.
- if (timeline_) {
- on_enter_after_phase_ = timeline_->QueueTask(
- *data_.start_time() + time_to_after_phase,
- base::Bind(&Animation::OnEnterAfterPhase, base::Unretained(this)));
- }
- } else {
- // We are already in the after phase, so clear this task.
- on_enter_after_phase_.reset();
- }
+ // We are already in the after phase, so clear this task.
+ on_enter_after_phase_.reset();
}
}
diff --git a/src/cobalt/web_animations/animation.h b/src/cobalt/web_animations/animation.h
index f7eb113..3240dbe 100644
--- a/src/cobalt/web_animations/animation.h
+++ b/src/cobalt/web_animations/animation.h
@@ -69,7 +69,9 @@
// Converts the animation's timeline's time into the animation's local
// time, which takes into account this animation's start_time().
base::optional<base::TimeDelta> ComputeLocalTimeFromTimelineTime(
- const base::optional<double>& timeline_time_in_milliseconds) const;
+ const base::optional<base::TimeDelta>& timeline_time) const;
+ base::optional<base::TimeDelta> ComputeTimelineTimeFromLocalTime(
+ const base::optional<base::TimeDelta>& local_time) const;
private:
base::optional<base::TimeDelta> start_time_;
@@ -128,6 +130,8 @@
}
base::optional<double> current_time() const;
+ base::optional<base::TimeDelta> current_time_as_time_delta() const;
+
void set_current_time(const base::optional<double>& current_time);
double playback_rate() const { return data_.playback_rate(); }
diff --git a/src/cobalt/web_animations/animation_test.cc b/src/cobalt/web_animations/animation_test.cc
index f07a57a..c4bba2b 100644
--- a/src/cobalt/web_animations/animation_test.cc
+++ b/src/cobalt/web_animations/animation_test.cc
@@ -32,7 +32,8 @@
TEST(AnimationDataTests, LocalTimeIsUnresolvedIfStartTimeIsUnresolved) {
Animation::Data animation;
base::optional<base::TimeDelta> local_time =
- animation.ComputeLocalTimeFromTimelineTime(3000.0);
+ animation.ComputeLocalTimeFromTimelineTime(
+ base::TimeDelta::FromMilliseconds(3000));
EXPECT_FALSE(local_time);
}
@@ -41,7 +42,8 @@
Animation::Data animation;
animation.set_start_time(base::TimeDelta::FromSeconds(2));
base::optional<base::TimeDelta> local_time =
- animation.ComputeLocalTimeFromTimelineTime(3000.0);
+ animation.ComputeLocalTimeFromTimelineTime(
+ base::TimeDelta::FromMilliseconds(3000));
ASSERT_TRUE(local_time);
EXPECT_EQ(1.0, local_time->InSecondsF());
@@ -52,7 +54,8 @@
animation.set_start_time(base::TimeDelta::FromSeconds(2));
animation.set_playback_rate(2.0);
base::optional<base::TimeDelta> local_time =
- animation.ComputeLocalTimeFromTimelineTime(3000.0);
+ animation.ComputeLocalTimeFromTimelineTime(
+ base::TimeDelta::FromMilliseconds(3000));
ASSERT_TRUE(local_time);
EXPECT_EQ(2.0, local_time->InSecondsF());
diff --git a/src/cobalt/web_animations/animation_timeline.cc b/src/cobalt/web_animations/animation_timeline.cc
index c006496..04adc73 100644
--- a/src/cobalt/web_animations/animation_timeline.cc
+++ b/src/cobalt/web_animations/animation_timeline.cc
@@ -41,7 +41,7 @@
// Returns the current time for the document. This is based off of the last
// sampled time.
// https://www.w3.org/TR/web-animations-1/#the-animationtimeline-interface
-base::optional<double> AnimationTimeline::current_time() {
+base::optional<double> AnimationTimeline::current_time() const {
if (sampled_clock_time_) {
return sampled_clock_time_->InMillisecondsF();
} else {
diff --git a/src/cobalt/web_animations/animation_timeline.h b/src/cobalt/web_animations/animation_timeline.h
index 57e0f57..3225f6f 100644
--- a/src/cobalt/web_animations/animation_timeline.h
+++ b/src/cobalt/web_animations/animation_timeline.h
@@ -39,10 +39,16 @@
// Returns the current sample time of the timeline, in milliseconds. If the
// returned optional is not engaged, this timeline is 'unresolved'.
- base::optional<double> current_time();
+ base::optional<double> current_time() const;
// Custom, not in any spec.
+ // Helper class to return the current time as a base::TimeDelta instead of a
+ // double.
+ const base::optional<base::TimeDelta>& current_time_as_time_delta() const {
+ return sampled_clock_time_;
+ }
+
// The owner of this timeline should call Sample() each time a new sample
// time is ready.
void Sample();
diff --git a/src/cobalt/web_animations/baked_animation_set.cc b/src/cobalt/web_animations/baked_animation_set.cc
index 63fce67..02d5f28 100644
--- a/src/cobalt/web_animations/baked_animation_set.cc
+++ b/src/cobalt/web_animations/baked_animation_set.cc
@@ -16,6 +16,8 @@
#include "cobalt/web_animations/baked_animation_set.h"
+#include <algorithm>
+
#include "cobalt/web_animations/animation_effect_read_only.h"
namespace cobalt {
@@ -33,8 +35,7 @@
cssom::CSSComputedStyleData* in_out_style) const {
// Get the animation's local time from the Animation::Data object.
base::optional<base::TimeDelta> local_time =
- animation_data_.ComputeLocalTimeFromTimelineTime(
- timeline_time.InMillisecondsF());
+ animation_data_.ComputeLocalTimeFromTimelineTime(timeline_time);
// Obtain the iteration progress from the AnimationEffectTimingReadOnly::Data
// object.
@@ -52,6 +53,13 @@
*iteration_progress.current_iteration);
}
+base::TimeDelta BakedAnimation::end_time() const {
+ base::TimeDelta end_time_local =
+ effect_timing_data_.time_until_after_phase(base::TimeDelta());
+
+ return *animation_data_.ComputeTimelineTimeFromLocalTime(end_time_local);
+}
+
BakedAnimationSet::BakedAnimationSet(const AnimationSet& animation_set) {
for (AnimationSet::InternalSet::const_iterator iter =
animation_set.animations().begin();
@@ -77,5 +85,15 @@
}
}
+base::TimeDelta BakedAnimationSet::end_time() const {
+ base::TimeDelta max_end_time = -base::TimeDelta::Max();
+ for (AnimationList::const_iterator iter = animations_.begin();
+ iter != animations_.end(); ++iter) {
+ base::TimeDelta animation_end_time = (*iter)->end_time();
+ max_end_time = std::max(animation_end_time, max_end_time);
+ }
+ return max_end_time;
+}
+
} // namespace web_animations
} // namespace cobalt
diff --git a/src/cobalt/web_animations/baked_animation_set.h b/src/cobalt/web_animations/baked_animation_set.h
index 4bdb083..b414aeb 100644
--- a/src/cobalt/web_animations/baked_animation_set.h
+++ b/src/cobalt/web_animations/baked_animation_set.h
@@ -49,6 +49,10 @@
void Apply(const base::TimeDelta& timeline_time,
cssom::CSSComputedStyleData* in_out_style) const;
+ // Returns the timeline time at which this animation will end. If the
+ // animation has no ending, base::TimeDelta::Max() will be returned.
+ base::TimeDelta end_time() const;
+
private:
const Animation::Data animation_data_;
const AnimationEffectTimingReadOnly::Data effect_timing_data_;
@@ -67,6 +71,10 @@
void Apply(const base::TimeDelta& timeline_time,
cssom::CSSComputedStyleData* in_out_style) const;
+ // Returns the timeline time at which point all animations in the set are
+ // ended, or base::TimeDelta::Max() if at leats one animation will never end.
+ base::TimeDelta end_time() const;
+
private:
typedef ScopedVector<BakedAnimation> AnimationList;
AnimationList animations_;
diff --git a/src/media/base/sbplayer_pipeline.cc b/src/media/base/sbplayer_pipeline.cc
index 971f574..9c09927 100644
--- a/src/media/base/sbplayer_pipeline.cc
+++ b/src/media/base/sbplayer_pipeline.cc
@@ -111,6 +111,18 @@
}
}
+// Used to post parameters to SbPlayerPipeline::StartTask() as the number of
+// parameters exceed what base::Bind() can support.
+struct StartTaskParameters {
+ scoped_refptr<Demuxer> demuxer;
+ SetDecryptorReadyCB decryptor_ready_cb;
+ PipelineStatusCB ended_cb;
+ PipelineStatusCB error_cb;
+ PipelineStatusCB seek_cb;
+ Pipeline::BufferingStateCB buffering_state_cb;
+ base::Closure duration_change_cb;
+};
+
class SetBoundsCaller : public base::RefCountedThreadSafe<SetBoundsCaller> {
public:
SetBoundsCaller() : player_(kSbPlayerInvalid) {}
@@ -180,7 +192,10 @@
typedef std::map<const void*, std::pair<scoped_refptr<DecoderBuffer>, int> >
DecodingBuffers;
- void StartTask();
+ void StartTask(const StartTaskParameters& parameters);
+ void SetVolumeTask(float volume);
+ void SetPlaybackRateTask(float volume);
+ void SetDurationTask(TimeDelta duration);
// DataSourceHost (by way of DemuxerHost) implementation.
void SetTotalBytes(int64 total_bytes) OVERRIDE;
@@ -222,20 +237,18 @@
void UpdateDecoderConfig(const scoped_refptr<DemuxerStream>& stream);
- // Message loop used to execute pipeline tasks.
+ // Message loop used to execute pipeline tasks. It is thread-safe.
scoped_refptr<base::MessageLoopProxy> message_loop_;
- // MediaLog to which to log events.
- scoped_refptr<MediaLog> media_log_;
-
- // Lock used to serialize access for the following data members.
- mutable base::Lock lock_;
-
- // The window this player associates with.
+ // The window this player associates with. It should only be assigned in the
+ // dtor and accesed once by SbPlayerCreate().
PipelineWindow window_;
- // Whether or not the pipeline is running.
- bool running_;
+ // The current ticket associated with the |player_|.
+ int ticket_;
+
+ // Lock used to serialize access for the following member variables.
+ mutable base::Lock lock_;
// Amount of available buffered data. Set by filters.
Ranges<int64> buffered_byte_ranges_;
@@ -261,12 +274,6 @@
// the filters.
float playback_rate_;
- // Status of the pipeline. Initialized to PIPELINE_OK which indicates that
- // the pipeline is operating correctly. Any other value indicates that the
- // pipeline is stopped or is stopping. Clients can call the Stop() method to
- // reset the pipeline state, and restore this to PIPELINE_OK.
- PipelineStatus status_;
-
// Whether the media contains rendered audio and video streams.
// TODO(fischman,scherkus): replace these with checks for
// {audio,video}_decoder_ once extraction of {Audio,Video}Decoder from the
@@ -274,15 +281,10 @@
bool has_audio_;
bool has_video_;
- int ticket_;
+ mutable PipelineStatistics statistics_;
- // The following data members are only accessed by tasks posted to
+ // The following member variables are only accessed by tasks posted to
// |message_loop_|.
- scoped_ptr<FilterCollection> filter_collection_;
-
- // Temporary callback used for Start() and Seek().
- PipelineStatusCB seek_cb_;
- SbMediaTime seek_time_;
// Temporary callback used for Stop().
base::Closure stop_cb_;
@@ -300,14 +302,20 @@
bool video_read_in_progress_;
TimeDelta duration_;
- mutable PipelineStatistics statistics_;
-
- SbPlayer player_;
-
DecodingBuffers decoding_buffers_;
-
scoped_refptr<SetBoundsCaller> set_bounds_caller_;
+ // The following member variables can be accessed from WMPI thread but all
+ // modifications to them happens on the pipeline thread. So any access of
+ // them from the WMPI thread and any modification to them on the pipeline
+ // thread has to guarded by lock. Access to them from the pipeline thread
+ // needn't to be guarded.
+
+ // Temporary callback used for Start() and Seek().
+ PipelineStatusCB seek_cb_;
+ SbMediaTime seek_time_;
+ SbPlayer player_;
+
DISALLOW_COPY_AND_ASSIGN(SbPlayerPipeline);
};
@@ -316,19 +324,19 @@
const scoped_refptr<base::MessageLoopProxy>& message_loop,
MediaLog* media_log)
: window_(window),
+ ticket_(SB_PLAYER_INITIAL_TICKET),
message_loop_(message_loop),
- media_log_(media_log),
total_bytes_(0),
natural_size_(0, 0),
volume_(1.f),
playback_rate_(0.f),
has_audio_(false),
has_video_(false),
- ticket_(SB_PLAYER_INITIAL_TICKET),
audio_read_in_progress_(false),
video_read_in_progress_(false),
- player_(kSbPlayerInvalid),
- set_bounds_caller_(new SetBoundsCaller) {}
+ set_bounds_caller_(new SetBoundsCaller),
+ seek_time_(0),
+ player_(kSbPlayerInvalid) {}
SbPlayerPipeline::~SbPlayerPipeline() {
DCHECK(player_ == kSbPlayerInvalid);
@@ -341,24 +349,19 @@
const PipelineStatusCB& seek_cb,
const BufferingStateCB& buffering_state_cb,
const base::Closure& duration_change_cb) {
- DCHECK(!filter_collection_);
DCHECK(filter_collection);
- // Assign the parameters here instead of posting it to StartTask() as the
- // number of parameters exceeds the maximum number of parameters that Bind
- // supports.
- filter_collection_ = filter_collection.Pass();
- decryptor_ready_cb_ = decryptor_ready_cb;
- ended_cb_ = ended_cb;
- error_cb_ = error_cb;
- seek_cb_ = seek_cb;
- buffering_state_cb_ = buffering_state_cb;
- duration_change_cb_ = duration_change_cb;
+ StartTaskParameters parameters;
+ parameters.demuxer = filter_collection->GetDemuxer();
+ parameters.decryptor_ready_cb = decryptor_ready_cb;
+ parameters.ended_cb = ended_cb;
+ parameters.error_cb = error_cb;
+ parameters.seek_cb = seek_cb;
+ parameters.buffering_state_cb = buffering_state_cb;
+ parameters.duration_change_cb = duration_change_cb;
- demuxer_ = filter_collection_->GetDemuxer();
-
- message_loop_->PostTask(FROM_HERE,
- base::Bind(&SbPlayerPipeline::StartTask, this));
+ message_loop_->PostTask(
+ FROM_HERE, base::Bind(&SbPlayerPipeline::StartTask, this, parameters));
}
void SbPlayerPipeline::Stop(const base::Closure& stop_cb) {
@@ -373,11 +376,17 @@
if (SbPlayerIsValid(player_)) {
set_bounds_caller_->SetPlayer(kSbPlayerInvalid);
+ SbPlayer player = player_;
+ {
+ base::AutoLock auto_lock(lock_);
+ player_ = kSbPlayerInvalid;
+ }
+
DLOG(INFO) << "Destroying SbPlayer.";
- SbPlayerDestroy(player_);
+ SbPlayerDestroy(player);
DLOG(INFO) << "SbPlayer destroyed.";
- player_ = kSbPlayerInvalid;
}
+
// When Stop() is in progress, we no longer need to call |error_cb_|.
error_cb_.Reset();
if (demuxer_) {
@@ -405,8 +414,11 @@
// Increase |ticket_| so all upcoming need data requests from the SbPlayer
// are ignored.
++ticket_;
- seek_cb_ = seek_cb;
- seek_time_ = TimeDeltaToSbMediaTime(time);
+ {
+ base::AutoLock auto_lock(lock_);
+ seek_cb_ = seek_cb;
+ seek_time_ = TimeDeltaToSbMediaTime(time);
+ }
demuxer_->Seek(time, BindToCurrentLoop(base::Bind(
&SbPlayerPipeline::OnDemuxerSeeked, this)));
}
@@ -432,9 +444,9 @@
base::AutoLock auto_lock(lock_);
playback_rate_ = playback_rate;
- if (SbPlayerIsValid(player_)) {
- SbPlayerSetPause(player_, playback_rate_ == 0.0);
- }
+ message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&SbPlayerPipeline::SetPlaybackRateTask, this, playback_rate));
}
float SbPlayerPipeline::GetVolume() const {
@@ -448,9 +460,8 @@
base::AutoLock auto_lock(lock_);
volume_ = volume;
- if (SbPlayerIsValid(player_)) {
- // SbPlayerSetVolume(player_, volume_);
- }
+ message_loop_->PostTask(
+ FROM_HERE, base::Bind(&SbPlayerPipeline::SetVolumeTask, this, volume));
}
TimeDelta SbPlayerPipeline::GetMediaTime() const {
@@ -526,14 +537,50 @@
#endif // SB_IS(PLAYER_PUNCHED_OUT)
}
-void SbPlayerPipeline::StartTask() {
+void SbPlayerPipeline::StartTask(const StartTaskParameters& parameters) {
DCHECK(message_loop_->BelongsToCurrentThread());
+ DCHECK(!demuxer_);
+
+ demuxer_ = parameters.demuxer;
+ decryptor_ready_cb_ = parameters.decryptor_ready_cb;
+ ended_cb_ = parameters.ended_cb;
+ error_cb_ = parameters.error_cb;
+ {
+ base::AutoLock auto_lock(lock_);
+ seek_cb_ = parameters.seek_cb;
+ }
+ buffering_state_cb_ = parameters.buffering_state_cb;
+ duration_change_cb_ = parameters.duration_change_cb;
+
demuxer_->Initialize(
this, BindToCurrentLoop(
base::Bind(&SbPlayerPipeline::OnDemuxerInitialized, this)));
}
+void SbPlayerPipeline::SetVolumeTask(float volume) {
+ DCHECK(message_loop_->BelongsToCurrentThread());
+
+ if (SbPlayerIsValid(player_)) {
+ SbPlayerSetVolume(player_, volume_);
+ }
+}
+
+void SbPlayerPipeline::SetPlaybackRateTask(float volume) {
+ DCHECK(message_loop_->BelongsToCurrentThread());
+
+ if (SbPlayerIsValid(player_)) {
+ SbPlayerSetPause(player_, playback_rate_ == 0.0);
+ }
+}
+
+void SbPlayerPipeline::SetDurationTask(TimeDelta duration) {
+ DCHECK(message_loop_->BelongsToCurrentThread());
+ if (!duration_change_cb_.is_null()) {
+ duration_change_cb_.Run();
+ }
+}
+
void SbPlayerPipeline::SetTotalBytes(int64 total_bytes) {
base::AutoLock auto_lock(lock_);
total_bytes_ = total_bytes;
@@ -542,11 +589,21 @@
void SbPlayerPipeline::SetDuration(TimeDelta duration) {
base::AutoLock auto_lock(lock_);
duration_ = duration;
- duration_change_cb_.Run();
+ message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&SbPlayerPipeline::SetDurationTask, this, duration));
}
void SbPlayerPipeline::OnDemuxerError(PipelineStatus error) {
- NOTIMPLEMENTED();
+ if (!message_loop_->BelongsToCurrentThread()) {
+ message_loop_->PostTask(
+ FROM_HERE, base::Bind(&SbPlayerPipeline::OnDemuxerError, this, error));
+ return;
+ }
+
+ if (error != PIPELINE_OK && !error_cb_.is_null()) {
+ base::ResetAndReturn(&error_cb_).Run(error);
+ }
}
void SbPlayerPipeline::AddBufferedByteRange(int64 start, int64 end) {
@@ -562,6 +619,8 @@
}
void SbPlayerPipeline::CreatePlayer(SbDrmSystem drm_system) {
+ DCHECK(message_loop_->BelongsToCurrentThread());
+
const AudioDecoderConfig& audio_config =
demuxer_->GetStream(DemuxerStream::AUDIO)->audio_decoder_config();
SbMediaAudioHeader audio_header;
@@ -573,14 +632,23 @@
audio_header.block_alignment = 4;
audio_header.bits_per_sample = audio_config.bits_per_channel();
audio_header.audio_specific_config_size = 0;
- player_ =
- SbPlayerCreate(window_, kSbMediaVideoCodecH264, kSbMediaAudioCodecAac,
- SB_PLAYER_NO_DURATION, drm_system, &audio_header,
- DeallocateSampleCB, DecoderStatusCB, PlayerStatusCB, this);
+
+ {
+ base::AutoLock auto_lock(lock_);
+ player_ = SbPlayerCreate(window_, kSbMediaVideoCodecH264,
+ kSbMediaAudioCodecAac, SB_PLAYER_NO_DURATION,
+ drm_system, &audio_header, DeallocateSampleCB,
+ DecoderStatusCB, PlayerStatusCB, this);
+ SetPlaybackRateTask(playback_rate_);
+ SetVolumeTask(volume_);
+ }
+
set_bounds_caller_->SetPlayer(player_);
}
void SbPlayerPipeline::SetDecryptor(Decryptor* decryptor) {
+ DCHECK(message_loop_->BelongsToCurrentThread());
+
if (!decryptor) {
return;
}
@@ -599,28 +667,30 @@
return;
}
- base::AutoLock auto_lock(lock_);
- has_audio_ = demuxer_->GetStream(DemuxerStream::AUDIO) != NULL;
- DCHECK(has_audio_);
- has_video_ = demuxer_->GetStream(DemuxerStream::VIDEO) != NULL;
+ {
+ base::AutoLock auto_lock(lock_);
+ has_audio_ = demuxer_->GetStream(DemuxerStream::AUDIO) != NULL;
+ DCHECK(has_audio_);
+ has_video_ = demuxer_->GetStream(DemuxerStream::VIDEO) != NULL;
- buffering_state_cb_.Run(kHaveMetadata);
+ buffering_state_cb_.Run(kHaveMetadata);
- NOTIMPLEMENTED() << "Dynamically determinate codecs";
+ NOTIMPLEMENTED() << "Dynamically determinate codecs";
- const AudioDecoderConfig& audio_config =
- demuxer_->GetStream(DemuxerStream::AUDIO)->audio_decoder_config();
- bool is_encrypted = audio_config.is_encrypted();
- if (has_video_) {
- const VideoDecoderConfig& video_config =
- demuxer_->GetStream(DemuxerStream::VIDEO)->video_decoder_config();
- natural_size_ = video_config.natural_size();
- is_encrypted |= video_config.is_encrypted();
- }
- if (is_encrypted) {
- decryptor_ready_cb_.Run(
- BindToCurrentLoop(base::Bind(&SbPlayerPipeline::SetDecryptor, this)));
- return;
+ const AudioDecoderConfig& audio_config =
+ demuxer_->GetStream(DemuxerStream::AUDIO)->audio_decoder_config();
+ bool is_encrypted = audio_config.is_encrypted();
+ if (has_video_) {
+ const VideoDecoderConfig& video_config =
+ demuxer_->GetStream(DemuxerStream::VIDEO)->video_decoder_config();
+ natural_size_ = video_config.natural_size();
+ is_encrypted |= video_config.is_encrypted();
+ }
+ if (is_encrypted) {
+ decryptor_ready_cb_.Run(
+ BindToCurrentLoop(base::Bind(&SbPlayerPipeline::SetDecryptor, this)));
+ return;
+ }
}
CreatePlayer(kSbDrmSystemInvalid);
@@ -642,7 +712,12 @@
}
void SbPlayerPipeline::OnDemuxerStopped() {
- base::AutoLock auto_lock(lock_);
+ if (!message_loop_->BelongsToCurrentThread()) {
+ message_loop_->PostTask(
+ FROM_HERE, base::Bind(&SbPlayerPipeline::OnDemuxerStopped, this));
+ return;
+ }
+
base::ResetAndReturn(&stop_cb_).Run();
}
@@ -685,7 +760,12 @@
}
if (!seek_cb_.is_null()) {
buffering_state_cb_.Run(kPrerollCompleted);
- base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
+ PipelineStatusCB seek_cb;
+ {
+ base::AutoLock auto_lock(lock_);
+ seek_cb = base::ResetAndReturn(&seek_cb_);
+ }
+ seek_cb.Run(PIPELINE_OK);
}
return;
}
@@ -807,7 +887,12 @@
case kSbPlayerStatePresenting:
buffering_state_cb_.Run(kPrerollCompleted);
if (!seek_cb_.is_null()) {
- base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
+ PipelineStatusCB seek_cb;
+ {
+ base::AutoLock auto_lock(lock_);
+ seek_cb = base::ResetAndReturn(&seek_cb_);
+ }
+ seek_cb.Run(PIPELINE_OK);
}
break;
case kSbPlayerStateEndOfStream:
@@ -816,7 +901,9 @@
case kSbPlayerStateDestroyed:
break;
case kSbPlayerStateError:
- // TODO: Handle error
+ if (!error_cb_.is_null()) {
+ base::ResetAndReturn(&error_cb_).Run(PIPELINE_ERROR_DECODE);
+ }
break;
}
}
@@ -843,7 +930,6 @@
SbPlayerDecoderState state,
int ticket) {
SbPlayerPipeline* pipeline = reinterpret_cast<SbPlayerPipeline*>(context);
- DCHECK_EQ(pipeline->player_, player);
pipeline->message_loop_->PostTask(
FROM_HERE, base::Bind(&SbPlayerPipeline::OnDecoderStatus, pipeline, type,
state, ticket));
@@ -865,7 +951,6 @@
void* context,
const void* sample_buffer) {
SbPlayerPipeline* pipeline = reinterpret_cast<SbPlayerPipeline*>(context);
- DCHECK_EQ(pipeline->player_, player);
pipeline->message_loop_->PostTask(
FROM_HERE, base::Bind(&SbPlayerPipeline::OnDeallocateSample, pipeline,
sample_buffer));
diff --git a/src/net/socket/tcp_client_socket_starboard.cc b/src/net/socket/tcp_client_socket_starboard.cc
index 042acd7..0a915a5 100644
--- a/src/net/socket/tcp_client_socket_starboard.cc
+++ b/src/net/socket/tcp_client_socket_starboard.cc
@@ -132,6 +132,25 @@
net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE);
}
+int TCPClientSocketStarboard::AdoptSocket(SbSocket socket) {
+ DCHECK(!SbSocketIsValid(socket_));
+
+ int error = SetupSocket(socket);
+ if (error) {
+ return error;
+ }
+
+ socket_ = socket;
+
+ // This is to make GetPeerAddress() work. It's up to the caller to ensure that
+ // |address_| contains a reasonable address for this socket. (i.e. at least
+ // match IPv4 vs IPv6!).
+ current_address_index_ = 0;
+ use_history_.set_was_ever_connected();
+
+ return OK;
+}
+
int TCPClientSocketStarboard::Connect(const CompletionCallback& callback) {
DCHECK(CalledOnValidThread());
diff --git a/src/net/udp/udp_listen_socket_unittest.cc b/src/net/udp/udp_listen_socket_unittest.cc
index 4f3a077..dddabd2 100644
--- a/src/net/udp/udp_listen_socket_unittest.cc
+++ b/src/net/udp/udp_listen_socket_unittest.cc
@@ -71,6 +71,7 @@
// Create another socket.
SocketDescriptor cs = SbSocketCreate(sb_address.type, kSbSocketProtocolUdp);
SbSocketSendTo(cs, data, size, &sb_address);
+ SbSocketDestroy(cs);
#else // defined(OS_STARBOARD)
// Get the watching address
SockaddrStorage bind_addr;
diff --git a/src/starboard/atomic.h b/src/starboard/atomic.h
index bdc3ad1..e47391f 100644
--- a/src/starboard/atomic.h
+++ b/src/starboard/atomic.h
@@ -41,23 +41,23 @@
// Always return the old value of "*ptr"
//
// This routine implies no memory barriers.
-SbAtomic32 SbAtomicNoBarrier_CompareAndSwap(volatile SbAtomic32* ptr,
- SbAtomic32 old_value,
- SbAtomic32 new_value);
+static SbAtomic32 SbAtomicNoBarrier_CompareAndSwap(volatile SbAtomic32* ptr,
+ SbAtomic32 old_value,
+ SbAtomic32 new_value);
// Atomically store new_value into *ptr, returning the previous value held in
// *ptr. This routine implies no memory barriers.
-SbAtomic32 SbAtomicNoBarrier_Exchange(volatile SbAtomic32* ptr,
- SbAtomic32 new_value);
+static SbAtomic32 SbAtomicNoBarrier_Exchange(volatile SbAtomic32* ptr,
+ SbAtomic32 new_value);
// Atomically increment *ptr by "increment". Returns the new value of
// *ptr with the increment applied. This routine implies no memory barriers.
-SbAtomic32 SbAtomicNoBarrier_Increment(volatile SbAtomic32* ptr,
- SbAtomic32 increment);
+static SbAtomic32 SbAtomicNoBarrier_Increment(volatile SbAtomic32* ptr,
+ SbAtomic32 increment);
// Same as SbAtomicNoBarrier_Increment, but with a memory barrier.
-SbAtomic32 SbAtomicBarrier_Increment(volatile SbAtomic32* ptr,
- SbAtomic32 increment);
+static SbAtomic32 SbAtomicBarrier_Increment(volatile SbAtomic32* ptr,
+ SbAtomic32 increment);
// These following lower-level operations are typically useful only to people
// implementing higher-level synchronization operations like spinlocks, mutexes,
@@ -68,54 +68,55 @@
// after the operation. "Barrier" operations have both "Acquire" and "Release"
// semantics. A SbAtomicMemoryBarrier() has "Barrier" semantics, but does no
// memory access.
-SbAtomic32 SbAtomicAcquire_CompareAndSwap(volatile SbAtomic32* ptr,
- SbAtomic32 old_value,
- SbAtomic32 new_value);
-SbAtomic32 SbAtomicRelease_CompareAndSwap(volatile SbAtomic32* ptr,
- SbAtomic32 old_value,
- SbAtomic32 new_value);
+static SbAtomic32 SbAtomicAcquire_CompareAndSwap(volatile SbAtomic32* ptr,
+ SbAtomic32 old_value,
+ SbAtomic32 new_value);
+static SbAtomic32 SbAtomicRelease_CompareAndSwap(volatile SbAtomic32* ptr,
+ SbAtomic32 old_value,
+ SbAtomic32 new_value);
-void SbAtomicMemoryBarrier();
-void SbAtomicNoBarrier_Store(volatile SbAtomic32* ptr, SbAtomic32 value);
-void SbAtomicAcquire_Store(volatile SbAtomic32* ptr, SbAtomic32 value);
-void SbAtomicRelease_Store(volatile SbAtomic32* ptr, SbAtomic32 value);
+static void SbAtomicMemoryBarrier();
+static void SbAtomicNoBarrier_Store(volatile SbAtomic32* ptr, SbAtomic32 value);
+static void SbAtomicAcquire_Store(volatile SbAtomic32* ptr, SbAtomic32 value);
+static void SbAtomicRelease_Store(volatile SbAtomic32* ptr, SbAtomic32 value);
-SbAtomic32 SbAtomicNoBarrier_Load(volatile const SbAtomic32* ptr);
-SbAtomic32 SbAtomicAcquire_Load(volatile const SbAtomic32* ptr);
-SbAtomic32 SbAtomicRelease_Load(volatile const SbAtomic32* ptr);
+static SbAtomic32 SbAtomicNoBarrier_Load(volatile const SbAtomic32* ptr);
+static SbAtomic32 SbAtomicAcquire_Load(volatile const SbAtomic32* ptr);
+static SbAtomic32 SbAtomicRelease_Load(volatile const SbAtomic32* ptr);
// 64-bit atomic operations (only available on 64-bit processors).
#if SB_HAS(64_BIT_ATOMICS)
typedef int64_t SbAtomic64;
-SbAtomic64 SbAtomicNoBarrier_CompareAndSwap64(volatile SbAtomic64* ptr,
- SbAtomic64 old_value,
- SbAtomic64 new_value);
-SbAtomic64 SbAtomicNoBarrier_Exchange64(volatile SbAtomic64* ptr,
- SbAtomic64 new_value);
-SbAtomic64 SbAtomicNoBarrier_Increment64(volatile SbAtomic64* ptr,
- SbAtomic64 increment);
-SbAtomic64 SbAtomicBarrier_Increment64(volatile SbAtomic64* ptr,
- SbAtomic64 increment);
-SbAtomic64 SbAtomicAcquire_CompareAndSwap64(volatile SbAtomic64* ptr,
- SbAtomic64 old_value,
- SbAtomic64 new_value);
-SbAtomic64 SbAtomicRelease_CompareAndSwap64(volatile SbAtomic64* ptr,
- SbAtomic64 old_value,
- SbAtomic64 new_value);
-void SbAtomicNoBarrier_Store64(volatile SbAtomic64* ptr, SbAtomic64 value);
-void SbAtomicAcquire_Store64(volatile SbAtomic64* ptr, SbAtomic64 value);
-void SbAtomicRelease_Store64(volatile SbAtomic64* ptr, SbAtomic64 value);
-SbAtomic64 SbAtomicNoBarrier_Load64(volatile const SbAtomic64* ptr);
-SbAtomic64 SbAtomicAcquire_Load64(volatile const SbAtomic64* ptr);
-SbAtomic64 SbAtomicRelease_Load64(volatile const SbAtomic64* ptr);
+static SbAtomic64 SbAtomicNoBarrier_CompareAndSwap64(volatile SbAtomic64* ptr,
+ SbAtomic64 old_value,
+ SbAtomic64 new_value);
+static SbAtomic64 SbAtomicNoBarrier_Exchange64(volatile SbAtomic64* ptr,
+ SbAtomic64 new_value);
+static SbAtomic64 SbAtomicNoBarrier_Increment64(volatile SbAtomic64* ptr,
+ SbAtomic64 increment);
+static SbAtomic64 SbAtomicBarrier_Increment64(volatile SbAtomic64* ptr,
+ SbAtomic64 increment);
+static SbAtomic64 SbAtomicAcquire_CompareAndSwap64(volatile SbAtomic64* ptr,
+ SbAtomic64 old_value,
+ SbAtomic64 new_value);
+static SbAtomic64 SbAtomicRelease_CompareAndSwap64(volatile SbAtomic64* ptr,
+ SbAtomic64 old_value,
+ SbAtomic64 new_value);
+static void SbAtomicNoBarrier_Store64(volatile SbAtomic64* ptr,
+ SbAtomic64 value);
+static void SbAtomicAcquire_Store64(volatile SbAtomic64* ptr, SbAtomic64 value);
+static void SbAtomicRelease_Store64(volatile SbAtomic64* ptr, SbAtomic64 value);
+static SbAtomic64 SbAtomicNoBarrier_Load64(volatile const SbAtomic64* ptr);
+static SbAtomic64 SbAtomicAcquire_Load64(volatile const SbAtomic64* ptr);
+static SbAtomic64 SbAtomicRelease_Load64(volatile const SbAtomic64* ptr);
#endif // SB_HAS(64_BIT_ATOMICS)
// Pointer-sized atomic operations. Forwards to either 32-bit or 64-bit
// functions as appropriate.
typedef intptr_t SbAtomicPtr;
-SB_C_FORCE_INLINE SbAtomicPtr
+static SB_C_FORCE_INLINE SbAtomicPtr
SbAtomicNoBarrier_CompareAndSwapPtr(volatile SbAtomicPtr* ptr,
SbAtomicPtr old_value,
SbAtomicPtr new_value) {
@@ -126,7 +127,7 @@
#endif
}
-SB_C_FORCE_INLINE SbAtomicPtr
+static SB_C_FORCE_INLINE SbAtomicPtr
SbAtomicNoBarrier_ExchangePtr(volatile SbAtomicPtr* ptr,
SbAtomicPtr new_value) {
#if SB_HAS(64_BIT_POINTERS)
@@ -136,7 +137,7 @@
#endif
}
-SB_C_FORCE_INLINE SbAtomicPtr
+static SB_C_FORCE_INLINE SbAtomicPtr
SbAtomicNoBarrier_IncrementPtr(volatile SbAtomicPtr* ptr,
SbAtomicPtr increment) {
#if SB_HAS(64_BIT_POINTERS)
@@ -146,7 +147,7 @@
#endif
}
-SB_C_FORCE_INLINE SbAtomicPtr
+static SB_C_FORCE_INLINE SbAtomicPtr
SbAtomicBarrier_IncrementPtr(volatile SbAtomicPtr* ptr, SbAtomicPtr increment) {
#if SB_HAS(64_BIT_POINTERS)
return SbAtomicBarrier_Increment64(ptr, increment);
@@ -155,7 +156,7 @@
#endif
}
-SB_C_FORCE_INLINE SbAtomicPtr
+static SB_C_FORCE_INLINE SbAtomicPtr
SbAtomicAcquire_CompareAndSwapPtr(volatile SbAtomicPtr* ptr,
SbAtomicPtr old_value,
SbAtomicPtr new_value) {
@@ -166,7 +167,7 @@
#endif
}
-SB_C_FORCE_INLINE SbAtomicPtr
+static SB_C_FORCE_INLINE SbAtomicPtr
SbAtomicRelease_CompareAndSwapPtr(volatile SbAtomicPtr* ptr,
SbAtomicPtr old_value,
SbAtomicPtr new_value) {
@@ -177,8 +178,8 @@
#endif
}
-SB_C_FORCE_INLINE void SbAtomicNoBarrier_StorePtr(volatile SbAtomicPtr* ptr,
- SbAtomicPtr value) {
+static SB_C_FORCE_INLINE void
+SbAtomicNoBarrier_StorePtr(volatile SbAtomicPtr* ptr, SbAtomicPtr value) {
#if SB_HAS(64_BIT_POINTERS)
return SbAtomicNoBarrier_Store64(ptr, value);
#else
@@ -186,8 +187,8 @@
#endif
}
-SB_C_FORCE_INLINE void SbAtomicAcquire_StorePtr(volatile SbAtomicPtr* ptr,
- SbAtomicPtr value) {
+static SB_C_FORCE_INLINE void
+SbAtomicAcquire_StorePtr(volatile SbAtomicPtr* ptr, SbAtomicPtr value) {
#if SB_HAS(64_BIT_POINTERS)
return SbAtomicAcquire_Store64(ptr, value);
#else
@@ -195,8 +196,8 @@
#endif
}
-SB_C_FORCE_INLINE void SbAtomicRelease_StorePtr(volatile SbAtomicPtr* ptr,
- SbAtomicPtr value) {
+static SB_C_FORCE_INLINE void
+SbAtomicRelease_StorePtr(volatile SbAtomicPtr* ptr, SbAtomicPtr value) {
#if SB_HAS(64_BIT_POINTERS)
return SbAtomicRelease_Store64(ptr, value);
#else
@@ -204,7 +205,7 @@
#endif
}
-SB_C_FORCE_INLINE SbAtomicPtr
+static SB_C_FORCE_INLINE SbAtomicPtr
SbAtomicNoBarrier_LoadPtr(volatile const SbAtomicPtr* ptr) {
#if SB_HAS(64_BIT_POINTERS)
return SbAtomicNoBarrier_Load64(ptr);
@@ -213,7 +214,7 @@
#endif
}
-SB_C_FORCE_INLINE SbAtomicPtr
+static SB_C_FORCE_INLINE SbAtomicPtr
SbAtomicAcquire_LoadPtr(volatile const SbAtomicPtr* ptr) {
#if SB_HAS(64_BIT_POINTERS)
return SbAtomicAcquire_Load64(ptr);
@@ -222,7 +223,7 @@
#endif
}
-SB_C_FORCE_INLINE SbAtomicPtr
+static SB_C_FORCE_INLINE SbAtomicPtr
SbAtomicRelease_LoadPtr(volatile const SbAtomicPtr* ptr) {
#if SB_HAS(64_BIT_POINTERS)
return SbAtomicRelease_Load64(ptr);
diff --git a/src/starboard/configuration.h b/src/starboard/configuration.h
index cff8fa8..e075b47 100644
--- a/src/starboard/configuration.h
+++ b/src/starboard/configuration.h
@@ -364,6 +364,10 @@
#error "Only one SB_HAS_{MANY, 1, 2, 4, 6}_CORE[S] can be defined per platform."
#endif
+#if !defined(SB_HAS_THREAD_PRIORITY_SUPPORT)
+#error "Your platform must define SB_HAS_THREAD_PRIORITY_SUPPORT."
+#endif
+
#if !defined(SB_PREFERRED_RGBA_BYTE_ORDER)
// Legal values for SB_PREFERRED_RGBA_BYTE_ORDER are defined in this file above
// as SB_PREFERRED_RGBA_BYTE_ORDER_*.
@@ -386,6 +390,10 @@
#error "Your platform must define SB_HAS_NV12_TEXTURE_SUPPORT."
#endif
+#if !defined(SB_MUST_FREQUENTLY_FLIP_DISPLAY_BUFFER)
+#error "Your platform must define SB_MUST_FREQUENTLY_FLIP_DISPLAY_BUFFER."
+#endif
+
// --- Derived Configuration -------------------------------------------------
// Whether the current platform is little endian.
diff --git a/src/starboard/file.h b/src/starboard/file.h
index d1ecc11..bda6f3a 100644
--- a/src/starboard/file.h
+++ b/src/starboard/file.h
@@ -178,6 +178,49 @@
// Converts an ISO fopen() mode string into flags that can be equivalently
// passed into SbFileOpen().
SB_EXPORT int SbFileModeStringToFlags(const char* mode);
+
+// Reads the given number of bytes (or until EOF is reached). Returns the number
+// of bytes read, or -1 on error. Note that this function makes a best effort to
+// read all data on all platforms, so it is not intended for stream oriented
+// files but instead for cases when the normal expectation is that actually
+// |size| bytes are read unless there is an error.
+static inline int SbFileReadAll(SbFile file, char* data, int size) {
+ if (!SbFileIsValid(file) || size < 0) {
+ return -1;
+ }
+ int bytes_read = 0;
+ int rv;
+ do {
+ rv = SbFileRead(file, data + bytes_read, size - bytes_read);
+ if (bytes_read <= 0) {
+ break;
+ }
+ bytes_read += rv;
+ } while (bytes_read < size);
+
+ return bytes_read ? bytes_read : rv;
+}
+
+// Writes the given buffer into the file, overwritting any data that was
+// previously there. Returns the number of bytes written, or -1 on error. Note
+// that this function makes a best effort to write all data on all platforms.
+static inline int SbFileWriteAll(SbFile file, const char* data, int size) {
+ if (!SbFileIsValid(file) || size < 0) {
+ return -1;
+ }
+ int bytes_written = 0;
+ int rv;
+ do {
+ rv = SbFileWrite(file, data + bytes_written, size - bytes_written);
+ if (bytes_written <= 0) {
+ break;
+ }
+ bytes_written += rv;
+ } while (bytes_written < size);
+
+ return bytes_written ? bytes_written : rv;
+}
+
#ifdef __cplusplus
} // extern "C"
#endif
@@ -219,10 +262,18 @@
int Read(char* data, int size) const { return SbFileRead(file_, data, size); }
+ int ReadAll(char* data, int size) const {
+ return SbFileReadAll(file_, data, size);
+ }
+
int Write(const char* data, int size) const {
return SbFileWrite(file_, data, size);
}
+ int WriteAll(const char* data, int size) const {
+ return SbFileWriteAll(file_, data, size);
+ }
+
bool Truncate(int64_t length) const { return SbFileTruncate(file_, length); }
bool Flush() const { return SbFileFlush(file_); }
@@ -231,6 +282,12 @@
return SbFileGetInfo(file_, out_info);
}
+ int64_t GetSize() const {
+ SbFileInfo file_info;
+ static bool success = GetInfo(&file_info);
+ return (success ? file_info.size : -1);
+ }
+
private:
SbFile file_;
};
diff --git a/src/starboard/input.h b/src/starboard/input.h
index dec4b29..fbce0f2 100644
--- a/src/starboard/input.h
+++ b/src/starboard/input.h
@@ -79,7 +79,7 @@
//
// Produces Move, Press, and Unpress events.
kSbInputDeviceTypeTouchPad,
-} SbInputType;
+} SbInputDeviceType;
// The action that an input event represents.
typedef enum SbInputEventType {
diff --git a/src/starboard/linux/shared/configuration_public.h b/src/starboard/linux/shared/configuration_public.h
index 624909f..9859ced 100644
--- a/src/starboard/linux/shared/configuration_public.h
+++ b/src/starboard/linux/shared/configuration_public.h
@@ -69,6 +69,12 @@
#define SB_IS_WCHAR_T_SIGNED 1
#endif
+// --- Architecture Configuration --------------------------------------------
+
+// On default Linux desktop, you must be a superuser in order to set real time
+// scheduling on threads.
+#define SB_HAS_THREAD_PRIORITY_SUPPORT 0
+
// --- Attribute Configuration -----------------------------------------------
// The platform's annotation for forcing a C function to be inlined.
@@ -232,6 +238,12 @@
// working properly.
#define SB_HAS_BILINEAR_FILTERING_SUPPORT 1
+// Whether the current platform should frequently flip their display buffer.
+// If this is not required (e.g. SB_MUST_FREQUENTLY_FLIP_DISPLAY_BUFFER is set
+// to 0), then optimizations where the display buffer is not flipped if the
+// scene hasn't changed are enabled.
+#define SB_MUST_FREQUENTLY_FLIP_DISPLAY_BUFFER 0
+
// --- Media Configuration ---------------------------------------------------
// Specifies whether this platform has support for a possibly-decrypting
@@ -288,7 +300,7 @@
// macro should be set to a value that is greater than the sum of the above
// source buffer stream memory limits with extra room to take account of
// fragmentations and memory used by demuxers.
-#define SB_MEDIA_MAIN_BUFFER_BUDGET (128U * 1024U * 1024U)
+#define SB_MEDIA_MAIN_BUFFER_BUDGET (32U * 1024U * 1024U)
// Specifies how much GPU memory to reserve up-front for media source buffers.
// This should only be set to non-zero on system with limited CPU memory and
diff --git a/src/starboard/linux/shared/gyp_configuration.gypi b/src/starboard/linux/shared/gyp_configuration.gypi
index 703b774..e4ca809 100644
--- a/src/starboard/linux/shared/gyp_configuration.gypi
+++ b/src/starboard/linux/shared/gyp_configuration.gypi
@@ -28,8 +28,7 @@
# This should have a default value in cobalt/base.gypi. See the comment
# there for acceptable values for this variable.
'javascript_engine': 'mozjs',
- # JIT is temporarily disabled for spidermonkey.
- 'cobalt_enable_jit': 0,
+ 'cobalt_enable_jit': 1,
# Define platform specific compiler and linker flags.
# Refer to base.gypi for a list of all available variables.
diff --git a/src/starboard/linux/x64x11/main.cc b/src/starboard/linux/x64x11/main.cc
index 7feb245..12cbce1 100644
--- a/src/starboard/linux/x64x11/main.cc
+++ b/src/starboard/linux/x64x11/main.cc
@@ -19,7 +19,7 @@
#include "starboard/shared/signal/suspend_signals.h"
#include "starboard/shared/x11/application_x11.h"
-int main(int argc, char** argv) {
+extern "C" SB_EXPORT_PLATFORM int main(int argc, char** argv) {
tzset();
starboard::shared::signal::InstallCrashSignalHandlers();
starboard::shared::signal::InstallSuspendSignalHandlers();
diff --git a/src/starboard/nplb/blitter_pixel_tests/data/MagnifyBlitRectToRectInterpolated-expected.png b/src/starboard/nplb/blitter_pixel_tests/data/MagnifyBlitRectToRectInterpolated-expected.png
new file mode 100644
index 0000000..27424c4
--- /dev/null
+++ b/src/starboard/nplb/blitter_pixel_tests/data/MagnifyBlitRectToRectInterpolated-expected.png
Binary files differ
diff --git a/src/starboard/nplb/blitter_pixel_tests/data/MagnifyBlitRectToRect-expected.png b/src/starboard/nplb/blitter_pixel_tests/data/MagnifyBlitRectToRectNotInterpolated-expected.png
similarity index 100%
rename from src/starboard/nplb/blitter_pixel_tests/data/MagnifyBlitRectToRect-expected.png
rename to src/starboard/nplb/blitter_pixel_tests/data/MagnifyBlitRectToRectNotInterpolated-expected.png
Binary files differ
diff --git a/src/starboard/nplb/blitter_pixel_tests/tests.cc b/src/starboard/nplb/blitter_pixel_tests/tests.cc
index 871c074..30c8a8b 100644
--- a/src/starboard/nplb/blitter_pixel_tests/tests.cc
+++ b/src/starboard/nplb/blitter_pixel_tests/tests.cc
@@ -101,7 +101,11 @@
SbBlitterMakeRect(0, 0, GetWidth(), GetHeight()));
}
-TEST_F(SbBlitterPixelTest, MagnifyBlitRectToRect) {
+#if SB_HAS(BILINEAR_FILTERING_SUPPORT)
+TEST_F(SbBlitterPixelTest, MagnifyBlitRectToRectInterpolated) {
+#else
+TEST_F(SbBlitterPixelTest, MagnifyBlitRectToRectNotInterpolated) {
+#endif
// Create an image with a height and width of 2x2.
SbBlitterSurface checker_image = CreateCheckerImageWithBlits(
device_, context_, SbBlitterColorFromRGBA(255, 255, 255, 255),
diff --git a/src/starboard/nplb/file_read_test.cc b/src/starboard/nplb/file_read_test.cc
index e294bca..a4c828d 100644
--- a/src/starboard/nplb/file_read_test.cc
+++ b/src/starboard/nplb/file_read_test.cc
@@ -22,17 +22,39 @@
namespace nplb {
namespace {
+// Sets up an empty test fixture, required for typed tests.
+template <class SbFileReadType>
+class SbFileReadTest : public testing::Test {};
+
+class SbFileReader {
+ public:
+ static int Read(SbFile file, char* data, int size) {
+ return SbFileRead(file, data, size);
+ }
+};
+
+class SbFileReaderAll {
+ public:
+ static int Read(SbFile file, char* data, int size) {
+ return SbFileReadAll(file, data, size);
+ }
+};
+
+typedef testing::Types<SbFileReader, SbFileReaderAll> SbFileReadTestTypes;
+
+TYPED_TEST_CASE(SbFileReadTest, SbFileReadTestTypes);
+
const int kBufferLength = 16 * 1024;
-TEST(SbFileReadTest, InvalidFileErrors) {
+TYPED_TEST(SbFileReadTest, InvalidFileErrors) {
char buffer[kBufferLength];
- int result = SbFileRead(kSbFileInvalid, buffer, kBufferLength);
+ int result = TypeParam::Read(kSbFileInvalid, buffer, kBufferLength);
EXPECT_EQ(-1, result);
}
-TEST(SbFileReadTest, BasicReading) {
- // Create a pattern file that is not an even multiple of the buffer size, but
- // is over several times the size of the buffer.
+TYPED_TEST(SbFileReadTest, BasicReading) {
+ // Create a pattern file that is not an even multiple of the buffer size,
+ // but is over several times the size of the buffer.
const int kFileSize = kBufferLength * 16 / 3;
ScopedRandomFile random_file(kFileSize);
const std::string& filename = random_file.filename();
@@ -41,8 +63,8 @@
SbFileOpen(filename.c_str(), kSbFileOpenOnly | kSbFileRead, NULL, NULL);
ASSERT_TRUE(SbFileIsValid(file));
- // Create a bigger buffer than necessary, so we can test the memory around the
- // portion given to SbFileRead.
+ // Create a bigger buffer than necessary, so we can test the memory around
+ // the portion given to SbFileRead.
const int kRealBufferLength = kBufferLength * 2;
char real_buffer[kRealBufferLength] = {0};
const int kBufferOffset = kBufferLength / 2;
@@ -58,7 +80,7 @@
int previous_total = 0;
int max = 0;
while (true) {
- int bytes_read = SbFileRead(file, buffer, kBufferLength);
+ int bytes_read = TypeParam::Read(file, buffer, kBufferLength);
if (bytes_read == 0) {
break;
}
@@ -96,7 +118,7 @@
EXPECT_TRUE(result);
}
-TEST(SbFileReadTest, ReadPastEnd) {
+TYPED_TEST(SbFileReadTest, ReadPastEnd) {
const int kFileSize = kBufferLength;
ScopedRandomFile random_file(kFileSize);
const std::string& filename = random_file.filename();
@@ -105,8 +127,8 @@
SbFileOpen(filename.c_str(), kSbFileOpenOnly | kSbFileRead, NULL, NULL);
ASSERT_TRUE(SbFileIsValid(file));
- // Create a bigger buffer than necessary, so we can test the memory around the
- // portion given to SbFileRead.
+ // Create a bigger buffer than necessary, so we can test the memory around
+ // the portion given to SbFileRead.
const int kRealBufferLength = kBufferLength * 2;
char real_buffer[kRealBufferLength] = {0};
const int kBufferOffset = kBufferLength / 2;
@@ -120,7 +142,7 @@
// Read off the end of the file.
int position = SbFileSeek(file, kSbFileFromEnd, 0);
EXPECT_EQ(kFileSize, position);
- int bytes_read = SbFileRead(file, buffer, kBufferLength);
+ int bytes_read = TypeParam::Read(file, buffer, kBufferLength);
EXPECT_EQ(0, bytes_read);
for (int i = 0; i < kRealBufferLength; ++i) {
@@ -131,7 +153,7 @@
EXPECT_TRUE(result);
}
-TEST(SbFileReadTest, ReadZeroBytes) {
+TYPED_TEST(SbFileReadTest, ReadZeroBytes) {
const int kFileSize = kBufferLength;
ScopedRandomFile random_file(kFileSize);
const std::string& filename = random_file.filename();
@@ -140,8 +162,8 @@
SbFileOpen(filename.c_str(), kSbFileOpenOnly | kSbFileRead, NULL, NULL);
ASSERT_TRUE(SbFileIsValid(file));
- // Create a bigger buffer than necessary, so we can test the memory around the
- // portion given to SbFileRead.
+ // Create a bigger buffer than necessary, so we can test the memory around
+ // the portion given to SbFileRead.
const int kRealBufferLength = kBufferLength * 2;
char real_buffer[kRealBufferLength] = {0};
const int kBufferOffset = kBufferLength / 2;
@@ -154,7 +176,7 @@
// Read zero bytes.
for (int i = 0; i < 10; ++i) {
- int bytes_read = SbFileRead(file, buffer, 0);
+ int bytes_read = TypeParam::Read(file, buffer, 0);
EXPECT_EQ(0, bytes_read);
}
@@ -166,7 +188,7 @@
EXPECT_TRUE(result);
}
-TEST(SbFileReadTest, ReadFromMiddle) {
+TYPED_TEST(SbFileReadTest, ReadFromMiddle) {
const int kFileSize = kBufferLength * 2;
ScopedRandomFile random_file(kFileSize);
const std::string& filename = random_file.filename();
@@ -175,8 +197,8 @@
SbFileOpen(filename.c_str(), kSbFileOpenOnly | kSbFileRead, NULL, NULL);
ASSERT_TRUE(SbFileIsValid(file));
- // Create a bigger buffer than necessary, so we can test the memory around the
- // portion given to SbFileRead.
+ // Create a bigger buffer than necessary, so we can test the memory around
+ // the portion given to SbFileRead.
const int kRealBufferLength = kBufferLength * 2;
char real_buffer[kRealBufferLength] = {0};
const int kBufferOffset = kBufferLength / 2;
@@ -190,7 +212,7 @@
// Read from the middle of the file.
int position = SbFileSeek(file, kSbFileFromBegin, kFileSize / 4);
EXPECT_EQ(kFileSize / 4, position);
- int bytes_read = SbFileRead(file, buffer, kBufferLength);
+ int bytes_read = TypeParam::Read(file, buffer, kBufferLength);
EXPECT_GE(kBufferLength, bytes_read);
EXPECT_LT(0, bytes_read);
diff --git a/src/starboard/nplb/file_write_test.cc b/src/starboard/nplb/file_write_test.cc
index 3b49a8d..e503a86 100644
--- a/src/starboard/nplb/file_write_test.cc
+++ b/src/starboard/nplb/file_write_test.cc
@@ -25,28 +25,50 @@
namespace nplb {
namespace {
+// Sets up an empty test fixture, required for typed tests.
+template <class SbFileWriteType>
+class SbFileWriteTest : public testing::Test {};
+
+class SbFileWriter {
+ public:
+ static int Write(SbFile file, char* data, int size) {
+ return SbFileWrite(file, data, size);
+ }
+};
+
+class SbFileWriterAll {
+ public:
+ static int Write(SbFile file, char* data, int size) {
+ return SbFileWriteAll(file, data, size);
+ }
+};
+
+typedef testing::Types<SbFileWriter, SbFileWriterAll> SbFileWriteTestTypes;
+
+TYPED_TEST_CASE(SbFileWriteTest, SbFileWriteTestTypes);
+
const int kBufferLength = 16 * 1024;
-TEST(SbFileWriteTest, InvalidFileErrors) {
+TYPED_TEST(SbFileWriteTest, InvalidFileErrors) {
char buffer[kBufferLength] = {0};
- int result = SbFileWrite(kSbFileInvalid, buffer, kBufferLength);
+ int result = TypeParam::Write(kSbFileInvalid, buffer, kBufferLength);
EXPECT_EQ(-1, result);
}
-TEST(SbFileWriteTest, BasicWriting) {
- // Choose a file size that is not an even multiple of the buffer size, but is
- // over several times the size of the buffer.
+TYPED_TEST(SbFileWriteTest, BasicWriting) {
+ // Choose a file size that is not an even multiple of the buffer size, but
+ // is over several times the size of the buffer.
const int kFileSize = kBufferLength * 16 / 3;
ScopedRandomFile random_file(0, ScopedRandomFile::kDontCreate);
const std::string& filename = random_file.filename();
- SbFile file =
- SbFileOpen(filename.c_str(),
- kSbFileCreateAlways | kSbFileWrite | kSbFileRead, NULL, NULL);
+ SbFile file = SbFileOpen(filename.c_str(),
+ kSbFileCreateAlways | kSbFileWrite | kSbFileRead,
+ NULL, NULL);
ASSERT_TRUE(SbFileIsValid(file));
- // Create a bigger buffer than necessary, so we can test the memory around the
- // portion given to SbFileRead.
+ // Create a bigger buffer than necessary, so we can test the memory around
+ // the portion given to SbFileRead.
char buffer[kBufferLength] = {0};
// Initialize to some arbitrary pattern so we can verify it later.
@@ -63,7 +85,7 @@
int remaining = kFileSize - total;
int to_write = remaining < kBufferLength ? remaining : kBufferLength;
- int bytes_written = SbFileWrite(file, buffer, to_write);
+ int bytes_written = TypeParam::Write(file, buffer, to_write);
// Check that we didn't write more than the buffer size.
EXPECT_GE(to_write, bytes_written);
@@ -85,7 +107,7 @@
total = 0;
int previous_total = 0;
while (true) {
- int bytes_read = SbFileRead(file, buffer, kBufferLength);
+ int bytes_read = SbFileReadAll(file, buffer, kBufferLength);
if (bytes_read == 0) {
break;
}
@@ -111,7 +133,7 @@
EXPECT_TRUE(result);
}
-TEST(SbFileWriteTest, WriteZeroBytes) {
+TYPED_TEST(SbFileWriteTest, WriteZeroBytes) {
ScopedRandomFile random_file(0, ScopedRandomFile::kDontCreate);
const std::string& filename = random_file.filename();
@@ -123,7 +145,7 @@
// Write zero bytes.
for (int i = 0; i < 10; ++i) {
- int bytes_written = SbFileWrite(file, buffer, 0);
+ int bytes_written = TypeParam::Write(file, buffer, 0);
EXPECT_EQ(0, bytes_written);
}
diff --git a/src/starboard/nplb/include_all.c b/src/starboard/nplb/include_all.c
index 95f0147..1ff7637 100644
--- a/src/starboard/nplb/include_all.c
+++ b/src/starboard/nplb/include_all.c
@@ -15,6 +15,7 @@
// Includes all headers in a C context to make sure they compile as C files.
#include "starboard/atomic.h"
+#include "starboard/audio_sink.h"
#include "starboard/blitter.h"
#include "starboard/byte_swap.h"
#include "starboard/character.h"
@@ -26,6 +27,7 @@
#include "starboard/event.h"
#include "starboard/export.h"
#include "starboard/file.h"
+#include "starboard/input.h"
#include "starboard/key.h"
#include "starboard/log.h"
#include "starboard/media.h"
diff --git a/src/starboard/nplb/include_all_too.c b/src/starboard/nplb/include_all_too.c
new file mode 100644
index 0000000..f7d6644
--- /dev/null
+++ b/src/starboard/nplb/include_all_too.c
@@ -0,0 +1,19 @@
+// Copyright 2015 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// A second translation unit that includes all the headers to verify there are
+// no duplicate symbols.
+
+#include "starboard/nplb/include_all.c"
+
diff --git a/src/starboard/nplb/nplb.gyp b/src/starboard/nplb/nplb.gyp
index 5b66821..1938621 100644
--- a/src/starboard/nplb/nplb.gyp
+++ b/src/starboard/nplb/nplb.gyp
@@ -100,6 +100,7 @@
'file_truncate_test.cc',
'file_write_test.cc',
'include_all.c',
+ 'include_all_too.c',
'log_flush_test.cc',
'log_format_test.cc',
'log_is_tty_test.cc',
diff --git a/src/starboard/raspi/shared/configuration_public.h b/src/starboard/raspi/shared/configuration_public.h
index b7ba3a6..03cb289 100644
--- a/src/starboard/raspi/shared/configuration_public.h
+++ b/src/starboard/raspi/shared/configuration_public.h
@@ -63,6 +63,14 @@
#define SB_IS_WCHAR_T_SIGNED 1
#endif
+// --- Architecture Configuration --------------------------------------------
+
+// On the current version of Raspbian, real time thread scheduling seems to be
+// broken in that higher priority threads do not always have priority over lower
+// priority threads. It looks like the thread created last will always have the
+// highest priority.
+#define SB_HAS_THREAD_PRIORITY_SUPPORT 0
+
// --- Attribute Configuration -----------------------------------------------
// The platform's annotation for forcing a C function to be inlined.
@@ -227,6 +235,12 @@
// textures. These textures typically originate from video decoders.
#define SB_HAS_NV12_TEXTURE_SUPPORT 1
+// Whether the current platform should frequently flip their display buffer.
+// If this is not required (e.g. SB_MUST_FREQUENTLY_FLIP_DISPLAY_BUFFER is set
+// to 0), then optimizations where the display buffer is not flipped if the
+// scene hasn't changed are enabled.
+#define SB_MUST_FREQUENTLY_FLIP_DISPLAY_BUFFER 0
+
// --- Media Configuration ---------------------------------------------------
// Specifies whether this platform has support for a possibly-decrypting
@@ -283,7 +297,7 @@
// macro should be set to a value that is greater than the sum of the above
// source buffer stream memory limits with extra room to take account of
// fragmentations and memory used by demuxers.
-#define SB_MEDIA_MAIN_BUFFER_BUDGET (128U * 1024U * 1024U)
+#define SB_MEDIA_MAIN_BUFFER_BUDGET (32U * 1024U * 1024U)
// Specifies how much GPU memory to reserve up-front for media source buffers.
// This should only be set to non-zero on system with limited CPU memory and
diff --git a/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.cc b/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.cc
index 9010e37..eafff4c 100644
--- a/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.cc
+++ b/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.cc
@@ -148,7 +148,9 @@
SbThreadJoin(decoder_thread_, NULL);
}
- avcodec_flush_buffers(codec_context_);
+ if (codec_context_ != NULL) {
+ avcodec_flush_buffers(codec_context_);
+ }
decoder_thread_ = kSbThreadInvalid;
stream_ended_ = false;
diff --git a/src/starboard/shared/gcc/atomic_gcc_public.h b/src/starboard/shared/gcc/atomic_gcc_public.h
index 655d2be..9c7afc6 100644
--- a/src/starboard/shared/gcc/atomic_gcc_public.h
+++ b/src/starboard/shared/gcc/atomic_gcc_public.h
@@ -24,7 +24,7 @@
extern "C" {
#endif
-SB_C_FORCE_INLINE SbAtomic32
+static SB_C_FORCE_INLINE SbAtomic32
SbAtomicNoBarrier_CompareAndSwap(volatile SbAtomic32* ptr,
SbAtomic32 old_value,
SbAtomic32 new_value) {
@@ -37,7 +37,7 @@
return prev_value;
}
-SB_C_FORCE_INLINE SbAtomic32
+static SB_C_FORCE_INLINE SbAtomic32
SbAtomicNoBarrier_Exchange(volatile SbAtomic32* ptr, SbAtomic32 new_value) {
SbAtomic32 old_value;
do {
@@ -46,13 +46,14 @@
return old_value;
}
-SB_C_FORCE_INLINE SbAtomic32
+static SB_C_FORCE_INLINE SbAtomic32
SbAtomicNoBarrier_Increment(volatile SbAtomic32* ptr, SbAtomic32 increment) {
return SbAtomicBarrier_Increment(ptr, increment);
}
-SB_C_FORCE_INLINE SbAtomic32 SbAtomicBarrier_Increment(volatile SbAtomic32* ptr,
- SbAtomic32 increment) {
+static SB_C_FORCE_INLINE SbAtomic32
+SbAtomicBarrier_Increment(volatile SbAtomic32* ptr,
+ SbAtomic32 increment) {
for (;;) {
// Atomic exchange the old value with an incremented one.
SbAtomic32 old_value = *ptr;
@@ -65,7 +66,7 @@
}
}
-SB_C_FORCE_INLINE SbAtomic32
+static SB_C_FORCE_INLINE SbAtomic32
SbAtomicAcquire_CompareAndSwap(volatile SbAtomic32* ptr,
SbAtomic32 old_value,
SbAtomic32 new_value) {
@@ -74,47 +75,47 @@
return SbAtomicNoBarrier_CompareAndSwap(ptr, old_value, new_value);
}
-SB_C_FORCE_INLINE SbAtomic32
+static SB_C_FORCE_INLINE SbAtomic32
SbAtomicRelease_CompareAndSwap(volatile SbAtomic32* ptr,
SbAtomic32 old_value,
SbAtomic32 new_value) {
return SbAtomicNoBarrier_CompareAndSwap(ptr, old_value, new_value);
}
-SB_C_FORCE_INLINE void SbAtomicMemoryBarrier() {
+static SB_C_FORCE_INLINE void SbAtomicMemoryBarrier() {
__sync_synchronize();
}
-SB_C_FORCE_INLINE void SbAtomicNoBarrier_Store(volatile SbAtomic32* ptr,
- SbAtomic32 value) {
+static SB_C_FORCE_INLINE void SbAtomicNoBarrier_Store(volatile SbAtomic32* ptr,
+ SbAtomic32 value) {
*ptr = value;
}
-SB_C_FORCE_INLINE void SbAtomicAcquire_Store(volatile SbAtomic32* ptr,
- SbAtomic32 value) {
+static SB_C_FORCE_INLINE void SbAtomicAcquire_Store(volatile SbAtomic32* ptr,
+ SbAtomic32 value) {
*ptr = value;
SbAtomicMemoryBarrier();
}
-SB_C_FORCE_INLINE void SbAtomicRelease_Store(volatile SbAtomic32* ptr,
- SbAtomic32 value) {
+static SB_C_FORCE_INLINE void SbAtomicRelease_Store(volatile SbAtomic32* ptr,
+ SbAtomic32 value) {
SbAtomicMemoryBarrier();
*ptr = value;
}
-SB_C_FORCE_INLINE SbAtomic32
+static SB_C_FORCE_INLINE SbAtomic32
SbAtomicNoBarrier_Load(volatile const SbAtomic32* ptr) {
return *ptr;
}
-SB_C_FORCE_INLINE SbAtomic32
+static SB_C_FORCE_INLINE SbAtomic32
SbAtomicAcquire_Load(volatile const SbAtomic32* ptr) {
SbAtomic32 value = *ptr;
SbAtomicMemoryBarrier();
return value;
}
-SB_C_FORCE_INLINE SbAtomic32
+static SB_C_FORCE_INLINE SbAtomic32
SbAtomicRelease_Load(volatile const SbAtomic32* ptr) {
SbAtomicMemoryBarrier();
return *ptr;
@@ -122,7 +123,7 @@
// 64-bit atomic operations (only available on 64-bit processors).
#if SB_HAS(64_BIT_ATOMICS)
-SB_C_FORCE_INLINE SbAtomic64
+static SB_C_FORCE_INLINE SbAtomic64
SbAtomicNoBarrier_CompareAndSwap64(volatile SbAtomic64* ptr,
SbAtomic64 old_value,
SbAtomic64 new_value) {
@@ -135,7 +136,7 @@
return prev_value;
}
-SB_C_FORCE_INLINE SbAtomic64
+static SB_C_FORCE_INLINE SbAtomic64
SbAtomicNoBarrier_Exchange64(volatile SbAtomic64* ptr, SbAtomic64 new_value) {
SbAtomic64 old_value;
do {
@@ -144,12 +145,12 @@
return old_value;
}
-SB_C_FORCE_INLINE SbAtomic64
+static SB_C_FORCE_INLINE SbAtomic64
SbAtomicNoBarrier_Increment64(volatile SbAtomic64* ptr, SbAtomic64 increment) {
return SbAtomicBarrier_Increment64(ptr, increment);
}
-SB_C_FORCE_INLINE SbAtomic64
+static SB_C_FORCE_INLINE SbAtomic64
SbAtomicBarrier_Increment64(volatile SbAtomic64* ptr, SbAtomic64 increment) {
for (;;) {
// Atomic exchange the old value with an incremented one.
@@ -163,50 +164,51 @@
}
}
-SB_C_FORCE_INLINE SbAtomic64
+static SB_C_FORCE_INLINE SbAtomic64
SbAtomicAcquire_CompareAndSwap64(volatile SbAtomic64* ptr,
SbAtomic64 old_value,
SbAtomic64 new_value) {
return SbAtomicNoBarrier_CompareAndSwap64(ptr, old_value, new_value);
}
-SB_C_FORCE_INLINE SbAtomic64
+static SB_C_FORCE_INLINE SbAtomic64
SbAtomicRelease_CompareAndSwap64(volatile SbAtomic64* ptr,
SbAtomic64 old_value,
SbAtomic64 new_value) {
return SbAtomicNoBarrier_CompareAndSwap64(ptr, old_value, new_value);
}
-SB_C_FORCE_INLINE void SbAtomicNoBarrier_Store64(volatile SbAtomic64* ptr,
- SbAtomic64 value) {
+static SB_C_FORCE_INLINE void
+SbAtomicNoBarrier_Store64(volatile SbAtomic64* ptr,
+ SbAtomic64 value) {
*ptr = value;
}
-SB_C_FORCE_INLINE void SbAtomicAcquire_Store64(volatile SbAtomic64* ptr,
- SbAtomic64 value) {
+static SB_C_FORCE_INLINE void SbAtomicAcquire_Store64(volatile SbAtomic64* ptr,
+ SbAtomic64 value) {
*ptr = value;
SbAtomicMemoryBarrier();
}
-SB_C_FORCE_INLINE void SbAtomicRelease_Store64(volatile SbAtomic64* ptr,
- SbAtomic64 value) {
+static SB_C_FORCE_INLINE void SbAtomicRelease_Store64(volatile SbAtomic64* ptr,
+ SbAtomic64 value) {
SbAtomicMemoryBarrier();
*ptr = value;
}
-SB_C_FORCE_INLINE SbAtomic64
+static SB_C_FORCE_INLINE SbAtomic64
SbAtomicNoBarrier_Load64(volatile const SbAtomic64* ptr) {
return *ptr;
}
-SB_C_FORCE_INLINE SbAtomic64
+static SB_C_FORCE_INLINE SbAtomic64
SbAtomicAcquire_Load64(volatile const SbAtomic64* ptr) {
SbAtomic64 value = *ptr;
SbAtomicMemoryBarrier();
return value;
}
-SB_C_FORCE_INLINE SbAtomic64
+static SB_C_FORCE_INLINE SbAtomic64
SbAtomicRelease_Load64(volatile const SbAtomic64* ptr) {
SbAtomicMemoryBarrier();
return *ptr;
diff --git a/src/starboard/shared/pthread/thread_create.cc b/src/starboard/shared/pthread/thread_create.cc
index 70a1fdb..1971d0d 100644
--- a/src/starboard/shared/pthread/thread_create.cc
+++ b/src/starboard/shared/pthread/thread_create.cc
@@ -1,4 +1,4 @@
-// Copyright 2015 Google Inc. All Rights Reserved.
+// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -16,17 +16,50 @@
#include <pthread.h>
#include <sched.h>
+#include <unistd.h>
+#include "starboard/log.h"
#include "starboard/shared/pthread/is_success.h"
#include "starboard/string.h"
+#if SB_HAS(THREAD_PRIORITY_SUPPORT)
+#if !defined(_POSIX_PRIORITY_SCHEDULING)
+#error "The _POSIX_PRIORITY_SCHEDULING define indicates that a pthreads \
+system supports thread priorities, however this define is not \
+defined on this system, contradicting the Starboard configuration \
+indicating that priority scheduling is supported."
+#endif // !defined(_POSIX_PRIORITY_SCHEDULING)
+#endif // SB_HAS(THREAD_PRIORITY_SUPPORT)
+
namespace {
+int SbThreadPriorityToPthread(SbThreadPriority priority) {
+ switch (priority) {
+ case kSbThreadPriorityLowest:
+ SB_NOTREACHED() << "Lowest priority threads should use SCHED_OTHER.";
+ return 0;
+ break;
+ case kSbThreadPriorityLow: return 2;
+ case kSbThreadNoPriority:
+ // Fall through on purpose to default to kThreadPriority_Normal.
+ case kSbThreadPriorityNormal: return 3;
+ case kSbThreadPriorityHigh: return 4;
+ case kSbThreadPriorityHighest: return 5;
+ case kSbThreadPriorityRealTime: return 6;
+ default:
+ SB_NOTREACHED();
+ return 0;
+ }
+}
+
struct ThreadParams {
SbThreadAffinity affinity;
SbThreadEntryPoint entry_point;
char name[128];
void* context;
+#if SB_HAS(THREAD_PRIORITY_SUPPORT)
+ SbThreadPriority priority;
+#endif // #if SB_HAS(THREAD_PRIORITY_SUPPORT)
};
void* ThreadFunc(void* context) {
@@ -38,6 +71,21 @@
SbThreadSetName(thread_params->name);
}
+#if SB_HAS(THREAD_PRIORITY_SUPPORT)
+ // Use Linux' regular scheduler for lowest priority threads. Real-time
+ // priority threads (of any priority) will always have priority over
+ // non-real-time threads (e.g. threads whose scheduler is setup to be
+ // SCHED_OTHER, the default scheduler).
+ if (thread_params->priority != kSbThreadPriorityLowest) {
+ // Note that use of sched_setscheduler() has been found to be more reliably
+ // supported than pthread_setschedparam(), so we are using that.
+ struct sched_param thread_sched_param;
+ thread_sched_param.sched_priority =
+ SbThreadPriorityToPthread(thread_params->priority);
+ sched_setscheduler(0, SCHED_FIFO, &thread_sched_param);
+ }
+#endif // #if SB_HAS(THREAD_PRIORITY_SUPPORT)
+
delete thread_params;
if (SbThreadIsValidAffinity(affinity)) {
@@ -84,10 +132,6 @@
pthread_attr_setstacksize(&attributes, stack_size);
}
- // Here is where we would use priority, but it doesn't really work on Linux
- // without using a realtime scheduling policy, according to this article:
- // http://stackoverflow.com/questions/3649281/how-to-increase-thread-priority-in-pthreads/3663250
-
ThreadParams* params = new ThreadParams();
params->affinity = affinity;
params->entry_point = entry_point;
@@ -99,6 +143,10 @@
params->name[0] = '\0';
}
+#if SB_HAS(THREAD_PRIORITY_SUPPORT)
+ params->priority = priority;
+#endif // #if SB_HAS(THREAD_PRIORITY_SUPPORT)
+
SbThread thread = kSbThreadInvalid;
result = pthread_create(&thread, &attributes, ThreadFunc, params);
diff --git a/src/starboard/shared/starboard/player/player_internal.cc b/src/starboard/shared/starboard/player/player_internal.cc
index 2c7c9f6..0443b2f 100644
--- a/src/starboard/shared/starboard/player/player_internal.cc
+++ b/src/starboard/shared/starboard/player/player_internal.cc
@@ -26,7 +26,8 @@
SbTimeMonotonic elapsed = SbTimeGetMonotonicNow() - media_pts_update_time;
return media_pts + elapsed * kSbMediaTimeSecond / kSbTimeSecond;
}
-}
+
+} // namespace
SbPlayerPrivate::SbPlayerPrivate(
SbWindow window,
diff --git a/src/starboard/shared/starboard/queue_application.cc b/src/starboard/shared/starboard/queue_application.cc
index 5a14ff2..6ef1cda 100644
--- a/src/starboard/shared/starboard/queue_application.cc
+++ b/src/starboard/shared/starboard/queue_application.cc
@@ -100,6 +100,15 @@
QueueApplication::TimedEventQueue::TimedEventQueue() : set_(&IsLess) {}
+QueueApplication::TimedEventQueue::~TimedEventQueue() {
+ ScopedLock lock(mutex_);
+ for (TimedEventMap::iterator i = map_.begin(); i != map_.end(); ++i) {
+ delete i->second;
+ }
+ map_.clear();
+ set_.clear();
+}
+
bool QueueApplication::TimedEventQueue::Inject(TimedEvent* timed_event) {
ScopedLock lock(mutex_);
SbTimeMonotonic oldTime = GetTimeLocked();
diff --git a/src/starboard/shared/starboard/queue_application.h b/src/starboard/shared/starboard/queue_application.h
index b48d8a7..1278dd0 100644
--- a/src/starboard/shared/starboard/queue_application.h
+++ b/src/starboard/shared/starboard/queue_application.h
@@ -85,6 +85,7 @@
class TimedEventQueue {
public:
TimedEventQueue();
+ ~TimedEventQueue();
// Returns whether the new event pushed up the next wakeup time.
bool Inject(TimedEvent* timed_event);
diff --git a/src/starboard/shared/starboard/shared_main_adapter.cc b/src/starboard/shared/starboard/shared_main_adapter.cc
new file mode 100644
index 0000000..2a6a911
--- /dev/null
+++ b/src/starboard/shared/starboard/shared_main_adapter.cc
@@ -0,0 +1,31 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Imports and calls into StarboardMain() from main(). Can be used to
+// link into a shared Starboard executable to turn it into a traditional
+// executable.
+
+#include "starboard/configuration.h"
+
+#undef main
+
+extern "C" {
+
+SB_IMPORT_PLATFORM int StarboardMain(int argc, char** argv);
+
+int main(int argc, char** argv) {
+ return StarboardMain(argc, argv);
+}
+
+} // extern "C"
diff --git a/src/starboard/shared/stub/system_get_number_of_processors.cc b/src/starboard/shared/stub/system_get_number_of_processors.cc
index b0f3a8c..a02ba16 100644
--- a/src/starboard/shared/stub/system_get_number_of_processors.cc
+++ b/src/starboard/shared/stub/system_get_number_of_processors.cc
@@ -15,5 +15,5 @@
#include "starboard/system.h"
int SbSystemGetNumberOfProcessors() {
- return 0;
+ return 1;
}
diff --git a/src/starboard/socket_waiter.h b/src/starboard/socket_waiter.h
index 894f74e..c964d6f 100644
--- a/src/starboard/socket_waiter.h
+++ b/src/starboard/socket_waiter.h
@@ -79,7 +79,7 @@
int ready_interests);
// Well-defined value for an invalid socket watcher handle.
-const SbSocketWaiter kSbSocketWaiterInvalid = (SbSocketWaiter)NULL;
+#define kSbSocketWaiterInvalid ((SbSocketWaiter)NULL)
// Returns whether the given socket handle is valid.
static SB_C_INLINE bool SbSocketWaiterIsValid(SbSocketWaiter watcher) {
diff --git a/src/starboard/starboard.gyp b/src/starboard/starboard.gyp
index 639b3dc..086ee4a 100644
--- a/src/starboard/starboard.gyp
+++ b/src/starboard/starboard.gyp
@@ -23,15 +23,31 @@
'type': 'none',
'sources': [
'atomic.h',
+ 'audio_sink.h',
+ 'blitter.h',
+ 'byte_swap.h',
+ 'character.h',
'condition_variable.h',
'configuration.h',
'directory.h',
'double.h',
+ 'drm.h',
+ 'event.h',
'export.h',
'file.h',
+ 'input.h',
+ 'key.h',
'log.h',
+ 'media.h',
'memory.h',
'mutex.h',
+ 'once.h',
+ 'player.h',
+ 'queue.h',
+ 'socket.h',
+ 'socket_waiter.h',
+ 'spin_lock.h',
+ 'storage.h',
'string.h',
'system.h',
'thread.h',
@@ -39,11 +55,13 @@
'time.h',
'time_zone.h',
'types.h',
+ 'user.h',
+ 'window.h',
],
'conditions': [
['starboard_path == ""', {
# TODO: Make starboard_path required. This legacy condition is only
- # here to support starboard-linux while it still exists.
+ # here to support semi-starboard platforms while they still exist.
'dependencies': [
'<(DEPTH)/starboard/<(target_arch)/starboard_platform.gyp:starboard_platform',
],
@@ -58,6 +76,17 @@
'<(DEPTH)/<(starboard_path)/starboard_platform.gyp:starboard_platform',
],
}],
+ ['final_executable_type=="shared_library"', {
+ 'all_dependent_settings': {
+ 'target_conditions': [
+ ['_type=="executable" and _toolset=="target"', {
+ 'sources': [
+ '<(DEPTH)/starboard/shared/starboard/shared_main_adapter.cc',
+ ],
+ }],
+ ],
+ },
+ }],
],
},
],
diff --git a/src/starboard/stub/configuration_public.h b/src/starboard/stub/configuration_public.h
index af9c671..5af547f 100644
--- a/src/starboard/stub/configuration_public.h
+++ b/src/starboard/stub/configuration_public.h
@@ -85,6 +85,9 @@
// Whether the current platform is expected to have exactly 6 cores.
#define SB_HAS_6_CORES 0
+// Whether the current platform supports thread priorities.
+#define SB_HAS_THREAD_PRIORITY_SUPPORT 0
+
// Whether the current platform's thread scheduler will automatically balance
// threads between cores, as opposed to systems where threads will only ever run
// on the specifically pinned core.
@@ -300,6 +303,12 @@
// textures. These textures typically originate from video decoders.
#define SB_HAS_NV12_TEXTURE_SUPPORT 0
+// Whether the current platform should frequently flip their display buffer.
+// If this is not required (e.g. SB_MUST_FREQUENTLY_FLIP_DISPLAY_BUFFER is set
+// to 0), then optimizations where the display buffer is not flipped if the
+// scene hasn't changed are enabled.
+#define SB_MUST_FREQUENTLY_FLIP_DISPLAY_BUFFER 0
+
// --- Media Configuration ---------------------------------------------------
// Specifies whether this platform has support for a possibly-decrypting
@@ -356,7 +365,7 @@
// macro should be set to a value that is greater than the sum of the above
// source buffer stream memory limits with extra room to take account of
// fragmentations and memory used by demuxers.
-#define SB_MEDIA_MAIN_BUFFER_BUDGET (128U * 1024U * 1024U)
+#define SB_MEDIA_MAIN_BUFFER_BUDGET (32U * 1024U * 1024U)
// Specifies how much GPU memory to reserve up-front for media source buffers.
// This should only be set to non-zero on system with limited CPU memory and
diff --git a/src/starboard/window.h b/src/starboard/window.h
index c3e25dd..44bb3e1 100644
--- a/src/starboard/window.h
+++ b/src/starboard/window.h
@@ -48,7 +48,7 @@
//
// Values greater than 1.0f mean that the video resolution is higher (denser,
// larger) than the graphics resolution. This is a common case as devices
- // often have less video decoding capabilities than graphics rendering
+ // often have more video decoding capabilities than graphics rendering
// capabilities (or memory, etc...).
//
// Values less than 1.0f mean that the maximum video resolution is smaller
@@ -74,7 +74,7 @@
} SbWindowOptions;
// Well-defined value for an invalid window handle.
-const SbWindow kSbWindowInvalid = (SbWindow)NULL;
+#define kSbWindowInvalid ((SbWindow)NULL)
// Returns whether the given window handle is valid.
static SB_C_INLINE bool SbWindowIsValid(SbWindow window) {
diff --git a/src/third_party/glm/CMakeLists.txt b/src/third_party/glm/CMakeLists.txt
new file mode 100644
index 0000000..bdb9f43
--- /dev/null
+++ b/src/third_party/glm/CMakeLists.txt
@@ -0,0 +1,227 @@
+cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
+cmake_policy(VERSION 2.6)
+if (NOT CMAKE_VERSION VERSION_LESS "3.1")
+ cmake_policy(SET CMP0054 NEW)
+endif()
+
+project(glm)
+set(GLM_VERSION "0.9.9")
+
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+
+include(GNUInstallDirs)
+include(CMakePackageConfigHelpers)
+
+enable_testing()
+
+add_definitions(-D_CRT_SECURE_NO_WARNINGS)
+
+option(GLM_STATIC_LIBRARY_ENABLE "GLM static library" OFF)
+if(GLM_STATIC_LIBRARY_ENABLE)
+ message(STATUS "GLM is a header only library, no need to build it. Set the option GLM_STATIC_LIBRARY_ENABLE with ON to build an optional static library")
+endif()
+
+option(GLM_DYNAMIC_LIBRARY_ENABLE "GLM static library" OFF)
+if(GLM_DYNAMIC_LIBRARY_ENABLE)
+ message(STATUS "GLM is a header only library, no need to build it. Set the option GLM_DYNAMIC_LIBRARY_ENABLE with ON to build an optional dynamic library")
+endif()
+
+option(GLM_TEST_ENABLE "GLM test" OFF)
+if(NOT GLM_TEST_ENABLE)
+ message(STATUS "GLM is a header only library, no need to build it. Set the option GLM_TEST_ENABLE with ON to build and run the test bench")
+endif()
+
+option(GLM_TEST_ENABLE_FAST_MATH "Enable fast math optimizations" OFF)
+
+if(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") OR ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") OR (("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") AND UNIX))
+ option(GLM_TEST_ENABLE_CXX_98 "Enable C++ 98" OFF)
+ option(GLM_TEST_ENABLE_CXX_0X "Enable C++ 0x" OFF)
+ option(GLM_TEST_ENABLE_CXX_11 "Enable C++ 11" OFF)
+ option(GLM_TEST_ENABLE_CXX_1Y "Enable C++ 1y" OFF)
+ option(GLM_TEST_ENABLE_CXX_14 "Enable C++ 14" OFF)
+ option(GLM_TEST_ENABLE_CXX_1Z "Enable C++ 1z" OFF)
+
+ if(GLM_TEST_ENABLE_CXX_1Z)
+ set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++1z")
+ set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
+ set(CMAKE_CXX_FLAGS "-std=c++1Z")
+ elseif(GLM_TEST_ENABLE_CXX_14)
+ set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++14")
+ set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
+ set(CMAKE_CXX_FLAGS "-std=c++14")
+ elseif(GLM_TEST_ENABLE_CXX_1Y)
+ set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++1y")
+ set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
+ set(CMAKE_CXX_FLAGS "-std=c++1y")
+ elseif(GLM_TEST_ENABLE_CXX_11)
+ set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11")
+ set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
+ set(CMAKE_CXX_FLAGS "-std=c++11")
+ elseif(GLM_TEST_ENABLE_CXX_0X)
+ set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++0x")
+ set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
+ set(CMAKE_CXX_FLAGS "-std=c++0x")
+ elseif(GLM_TEST_ENABLE_CXX_98)
+ set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++98")
+ set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
+ set(CMAKE_CXX_FLAGS "-std=c++98")
+ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+ add_definitions(-Wno-long-long)
+ endif()
+ endif()
+endif()
+
+option(GLM_TEST_ENABLE_LANG_EXTENSIONS "Enable language extensions" OFF)
+
+if(GLM_TEST_ENABLE_LANG_EXTENSIONS)
+ if(GLM_TEST_ENABLE_FAST_MATH)
+ if(CMAKE_COMPILER_IS_GNUCXX)
+ add_definitions(-ffast-math)
+ endif()
+
+ if(MSVC)
+ add_definitions(/fp:fast)
+ endif()
+ elseif(NOT GLM_TEST_ENABLE_FAST_MATH)
+ if(MSVC)
+ add_definitions(/fp:precise)
+ endif()
+ endif()
+else()
+ if(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") OR (("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") AND WIN32))
+ add_definitions(/Za)
+ elseif(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") OR ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU"))
+ add_definitions(-pedantic)
+ endif()
+endif()
+
+option(GLM_TEST_ENABLE_SIMD_SSE2 "Enable SSE2 optimizations" OFF)
+option(GLM_TEST_ENABLE_SIMD_SSE3 "Enable SSE3 optimizations" OFF)
+option(GLM_TEST_ENABLE_SIMD_AVX "Enable AVX optimizations" OFF)
+option(GLM_TEST_ENABLE_SIMD_AVX2 "Enable AVX2 optimizations" OFF)
+option(GLM_TEST_FORCE_PURE "Force 'pure' instructions" OFF)
+
+if(GLM_TEST_FORCE_PURE)
+ add_definitions(-DGLM_FORCE_PURE)
+
+ if(CMAKE_COMPILER_IS_GNUCXX)
+ add_definitions(-mfpmath=387)
+ endif()
+elseif(GLM_TEST_ENABLE_SIMD_AVX2)
+ if(CMAKE_COMPILER_IS_GNUCXX)
+ add_definitions(-mavx2)
+ elseif(GLM_USE_INTEL)
+ add_definitions(/QxAVX2)
+ elseif(MSVC)
+ add_definitions(/arch:AVX2)
+ endif()
+elseif(GLM_TEST_ENABLE_SIMD_AVX)
+ if(CMAKE_COMPILER_IS_GNUCXX)
+ add_definitions(-mavx)
+ elseif(GLM_USE_INTEL)
+ add_definitions(/QxAVX)
+ elseif(MSVC)
+ add_definitions(/arch:AVX)
+ endif()
+elseif(GLM_TEST_ENABLE_SIMD_SSE3)
+ if(CMAKE_COMPILER_IS_GNUCXX)
+ add_definitions(-msse3)
+ elseif(GLM_USE_INTEL)
+ add_definitions(/QxSSE3)
+ elseif(MSVC AND NOT CMAKE_CL_64)
+ add_definitions(/arch:SSE2) # VC doesn't support /arch:SSE3
+ endif()
+elseif(GLM_TEST_ENABLE_SIMD_SSE2)
+ if(CMAKE_COMPILER_IS_GNUCXX)
+ add_definitions(-msse2)
+ elseif(GLM_USE_INTEL)
+ add_definitions(/QxSSE2)
+ elseif(MSVC AND NOT CMAKE_CL_64)
+ add_definitions(/arch:SSE2)
+ endif()
+endif()
+
+if(CMAKE_COMPILER_IS_GNUCXX)
+ #add_definitions(-S)
+ #add_definitions(-s)
+ add_definitions(-O2)
+
+ #add_definitions(-fprofile-arcs -ftest-coverage) gcov
+ #ctest_enable_coverage()
+endif()
+
+if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
+ add_definitions(/FAs)
+endif()
+
+include_directories("${PROJECT_SOURCE_DIR}")
+include_directories("${PROJECT_SOURCE_DIR}/test/external")
+
+add_subdirectory(glm)
+add_subdirectory(test)
+
+set(GLM_INSTALL_CONFIGDIR "${CMAKE_INSTALL_LIBDIR}/cmake/glm")
+install(DIRECTORY glm DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
+
+write_basic_package_version_file(
+ "${CMAKE_CURRENT_BINARY_DIR}/glmVersion.cmake"
+ VERSION ${GLM_VERSION}
+ COMPATIBILITY AnyNewerVersion
+)
+
+# build tree package config
+configure_file(
+ cmake/glmBuildConfig.cmake.in
+ glmConfig.cmake
+ @ONLY
+)
+
+# install tree package config
+configure_package_config_file(
+ cmake/glmConfig.cmake.in
+ ${GLM_INSTALL_CONFIGDIR}/glmConfig.cmake
+ INSTALL_DESTINATION ${GLM_INSTALL_CONFIGDIR}
+ PATH_VARS CMAKE_INSTALL_INCLUDEDIR
+ NO_CHECK_REQUIRED_COMPONENTS_MACRO
+)
+
+install(
+ FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/${GLM_INSTALL_CONFIGDIR}/glmConfig.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/glmVersion.cmake"
+ DESTINATION ${GLM_INSTALL_CONFIGDIR}
+)
+
+if (NOT CMAKE_VERSION VERSION_LESS "3.0")
+ add_library(glm INTERFACE)
+ target_include_directories(glm INTERFACE
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+ )
+ install(TARGETS glm EXPORT glmTargets)
+
+ export(
+ EXPORT glmTargets
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/glmTargets.cmake"
+ )
+
+ install(
+ EXPORT glmTargets FILE glmTargets.cmake
+ DESTINATION ${GLM_INSTALL_CONFIGDIR}
+ )
+endif()
+
+# build pkg-config file
+configure_file(
+ "./cmake/glm.pc.in"
+ "glm.pc"
+ @ONLY
+)
+
+# install pkg-config file
+install(
+ FILES "${CMAKE_CURRENT_BINARY_DIR}/glm.pc"
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
+)
+
+export(PACKAGE glm)
diff --git a/src/third_party/glm/cmake/CMakePackageConfigHelpers.cmake b/src/third_party/glm/cmake/CMakePackageConfigHelpers.cmake
new file mode 100644
index 0000000..d5bf4a2
--- /dev/null
+++ b/src/third_party/glm/cmake/CMakePackageConfigHelpers.cmake
@@ -0,0 +1,227 @@
+# - CONFIGURE_PACKAGE_CONFIG_FILE(), WRITE_BASIC_PACKAGE_VERSION_FILE()
+#
+# CONFIGURE_PACKAGE_CONFIG_FILE(<input> <output> INSTALL_DESTINATION <path>
+# [PATH_VARS <var1> <var2> ... <varN>]
+# [NO_SET_AND_CHECK_MACRO]
+# [NO_CHECK_REQUIRED_COMPONENTS_MACRO])
+#
+# CONFIGURE_PACKAGE_CONFIG_FILE() should be used instead of the plain
+# CONFIGURE_FILE() command when creating the <Name>Config.cmake or <Name>-config.cmake
+# file for installing a project or library. It helps making the resulting package
+# relocatable by avoiding hardcoded paths in the installed Config.cmake file.
+#
+# In a FooConfig.cmake file there may be code like this to make the
+# install destinations know to the using project:
+# set(FOO_INCLUDE_DIR "@CMAKE_INSTALL_FULL_INCLUDEDIR@" )
+# set(FOO_DATA_DIR "@CMAKE_INSTALL_PREFIX@/@RELATIVE_DATA_INSTALL_DIR@" )
+# set(FOO_ICONS_DIR "@CMAKE_INSTALL_PREFIX@/share/icons" )
+# ...logic to determine installedPrefix from the own location...
+# set(FOO_CONFIG_DIR "${installedPrefix}/@CONFIG_INSTALL_DIR@" )
+# All 4 options shown above are not sufficient, since the first 3 hardcode
+# the absolute directory locations, and the 4th case works only if the logic
+# to determine the installedPrefix is correct, and if CONFIG_INSTALL_DIR contains
+# a relative path, which in general cannot be guaranteed.
+# This has the effect that the resulting FooConfig.cmake file would work poorly
+# under Windows and OSX, where users are used to choose the install location
+# of a binary package at install time, independent from how CMAKE_INSTALL_PREFIX
+# was set at build/cmake time.
+#
+# Using CONFIGURE_PACKAGE_CONFIG_FILE() helps. If used correctly, it makes the
+# resulting FooConfig.cmake file relocatable.
+# Usage:
+# 1. write a FooConfig.cmake.in file as you are used to
+# 2. insert a line containing only the string "@PACKAGE_INIT@"
+# 3. instead of SET(FOO_DIR "@SOME_INSTALL_DIR@"), use SET(FOO_DIR "@PACKAGE_SOME_INSTALL_DIR@")
+# (this must be after the @PACKAGE_INIT@ line)
+# 4. instead of using the normal CONFIGURE_FILE(), use CONFIGURE_PACKAGE_CONFIG_FILE()
+#
+# The <input> and <output> arguments are the input and output file, the same way
+# as in CONFIGURE_FILE().
+#
+# The <path> given to INSTALL_DESTINATION must be the destination where the FooConfig.cmake
+# file will be installed to. This can either be a relative or absolute path, both work.
+#
+# The variables <var1> to <varN> given as PATH_VARS are the variables which contain
+# install destinations. For each of them the macro will create a helper variable
+# PACKAGE_<var...>. These helper variables must be used
+# in the FooConfig.cmake.in file for setting the installed location. They are calculated
+# by CONFIGURE_PACKAGE_CONFIG_FILE() so that they are always relative to the
+# installed location of the package. This works both for relative and also for absolute locations.
+# For absolute locations it works only if the absolute location is a subdirectory
+# of CMAKE_INSTALL_PREFIX.
+#
+# By default configure_package_config_file() also generates two helper macros,
+# set_and_check() and check_required_components() into the FooConfig.cmake file.
+#
+# set_and_check() should be used instead of the normal set()
+# command for setting directories and file locations. Additionally to setting the
+# variable it also checks that the referenced file or directory actually exists
+# and fails with a FATAL_ERROR otherwise. This makes sure that the created
+# FooConfig.cmake file does not contain wrong references.
+# When using the NO_SET_AND_CHECK_MACRO, this macro is not generated into the
+# FooConfig.cmake file.
+#
+# check_required_components(<package_name>) should be called at the end of the
+# FooConfig.cmake file if the package supports components.
+# This macro checks whether all requested, non-optional components have been found,
+# and if this is not the case, sets the Foo_FOUND variable to FALSE, so that the package
+# is considered to be not found.
+# It does that by testing the Foo_<Component>_FOUND variables for all requested
+# required components.
+# When using the NO_CHECK_REQUIRED_COMPONENTS option, this macro is not generated
+# into the FooConfig.cmake file.
+#
+# For an example see below the documentation for WRITE_BASIC_PACKAGE_VERSION_FILE().
+#
+#
+# WRITE_BASIC_PACKAGE_VERSION_FILE( filename VERSION major.minor.patch COMPATIBILITY (AnyNewerVersion|SameMajorVersion|ExactVersion) )
+#
+# Writes a file for use as <package>ConfigVersion.cmake file to <filename>.
+# See the documentation of FIND_PACKAGE() for details on this.
+# filename is the output filename, it should be in the build tree.
+# major.minor.patch is the version number of the project to be installed
+# The COMPATIBILITY mode AnyNewerVersion means that the installed package version
+# will be considered compatible if it is newer or exactly the same as the requested version.
+# This mode should be used for packages which are fully backward compatible,
+# also across major versions.
+# If SameMajorVersion is used instead, then the behaviour differs from AnyNewerVersion
+# in that the major version number must be the same as requested, e.g. version 2.0 will
+# not be considered compatible if 1.0 is requested.
+# This mode should be used for packages which guarantee backward compatibility within the
+# same major version.
+# If ExactVersion is used, then the package is only considered compatible if the requested
+# version matches exactly its own version number (not considering the tweak version).
+# For example, version 1.2.3 of a package is only considered compatible to requested version 1.2.3.
+# This mode is for packages without compatibility guarantees.
+# If your project has more elaborated version matching rules, you will need to write your
+# own custom ConfigVersion.cmake file instead of using this macro.
+#
+# Internally, this macro executes configure_file() to create the resulting
+# version file. Depending on the COMPATIBILITY, either the file
+# BasicConfigVersion-SameMajorVersion.cmake.in or BasicConfigVersion-AnyNewerVersion.cmake.in
+# is used. Please note that these two files are internal to CMake and you should
+# not call configure_file() on them yourself, but they can be used as starting
+# point to create more sophisticted custom ConfigVersion.cmake files.
+#
+#
+# Example using both configure_package_config_file() and write_basic_package_version_file():
+# CMakeLists.txt:
+# set(INCLUDE_INSTALL_DIR include/ ... CACHE )
+# set(LIB_INSTALL_DIR lib/ ... CACHE )
+# set(SYSCONFIG_INSTALL_DIR etc/foo/ ... CACHE )
+# ...
+# include(CMakePackageConfigHelpers)
+# configure_package_config_file(FooConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake
+# INSTALL_DESTINATION ${LIB_INSTALL_DIR}/Foo/cmake
+# PATH_VARS INCLUDE_INSTALL_DIR SYSCONFIG_INSTALL_DIR)
+# write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
+# VERSION 1.2.3
+# COMPATIBILITY SameMajorVersion )
+# install(FILES ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
+# DESTINATION ${LIB_INSTALL_DIR}/Foo/cmake )
+#
+# With a FooConfig.cmake.in:
+# set(FOO_VERSION x.y.z)
+# ...
+# @PACKAGE_INIT@
+# ...
+# set_and_check(FOO_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
+# set_and_check(FOO_SYSCONFIG_DIR "@PACKAGE_SYSCONFIG_INSTALL_DIR@")
+#
+# check_required_components(Foo)
+
+
+#=============================================================================
+# Copyright 2012 Alexander Neundorf <neundorf@kde.org>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+include(CMakeParseArguments)
+
+include(WriteBasicConfigVersionFile)
+
+macro(WRITE_BASIC_PACKAGE_VERSION_FILE)
+ write_basic_config_version_file(${ARGN})
+endmacro()
+
+
+function(CONFIGURE_PACKAGE_CONFIG_FILE _inputFile _outputFile)
+ set(options NO_SET_AND_CHECK_MACRO NO_CHECK_REQUIRED_COMPONENTS_MACRO)
+ set(oneValueArgs INSTALL_DESTINATION )
+ set(multiValueArgs PATH_VARS )
+
+ cmake_parse_arguments(CCF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ if(CCF_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Unknown keywords given to CONFIGURE_PACKAGE_CONFIG_FILE(): \"${CCF_UNPARSED_ARGUMENTS}\"")
+ endif()
+
+ if(NOT CCF_INSTALL_DESTINATION)
+ message(FATAL_ERROR "No INSTALL_DESTINATION given to CONFIGURE_PACKAGE_CONFIG_FILE()")
+ endif()
+
+ if(IS_ABSOLUTE "${CCF_INSTALL_DESTINATION}")
+ set(absInstallDir "${CCF_INSTALL_DESTINATION}")
+ else()
+ set(absInstallDir "${CMAKE_INSTALL_PREFIX}/${CCF_INSTALL_DESTINATION}")
+ endif()
+ file(RELATIVE_PATH PACKAGE_RELATIVE_PATH "${absInstallDir}" "${CMAKE_INSTALL_PREFIX}" )
+
+ foreach(var ${CCF_PATH_VARS})
+ if(NOT DEFINED ${var})
+ message(FATAL_ERROR "Variable ${var} does not exist")
+ else()
+ if(IS_ABSOLUTE "${${var}}")
+ string(REPLACE "${CMAKE_INSTALL_PREFIX}" "\${PACKAGE_PREFIX_DIR}"
+ PACKAGE_${var} "${${var}}")
+ else()
+ set(PACKAGE_${var} "\${PACKAGE_PREFIX_DIR}/${${var}}")
+ endif()
+ endif()
+ endforeach()
+
+ set(PACKAGE_INIT "
+####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
+get_filename_component(PACKAGE_PREFIX_DIR \"\${CMAKE_CURRENT_LIST_DIR}/${PACKAGE_RELATIVE_PATH}\" ABSOLUTE)
+")
+
+ if(NOT CCF_NO_SET_AND_CHECK_MACRO)
+ set(PACKAGE_INIT "${PACKAGE_INIT}
+macro(set_and_check _var _file)
+ set(\${_var} \"\${_file}\")
+ if(NOT EXISTS \"\${_file}\")
+ message(FATAL_ERROR \"File or directory \${_file} referenced by variable \${_var} does not exist !\")
+ endif()
+endmacro()
+")
+ endif()
+
+
+ if(NOT CCF_NO_CHECK_REQUIRED_COMPONENTS_MACRO)
+ set(PACKAGE_INIT "${PACKAGE_INIT}
+macro(check_required_components _NAME)
+ foreach(comp \${\${_NAME}_FIND_COMPONENTS})
+ if(NOT \${_NAME}_\${comp}_FOUND)
+ if(\${_NAME}_FIND_REQUIRED_\${comp})
+ set(\${_NAME}_FOUND FALSE)
+ endif()
+ endif()
+ endforeach(comp)
+endmacro()
+")
+ endif()
+
+ set(PACKAGE_INIT "${PACKAGE_INIT}
+####################################################################################")
+
+ configure_file("${_inputFile}" "${_outputFile}" @ONLY)
+
+endfunction()
diff --git a/src/third_party/glm/cmake/GNUInstallDirs.cmake b/src/third_party/glm/cmake/GNUInstallDirs.cmake
new file mode 100644
index 0000000..4dc2d68
--- /dev/null
+++ b/src/third_party/glm/cmake/GNUInstallDirs.cmake
@@ -0,0 +1,188 @@
+# - Define GNU standard installation directories
+# Provides install directory variables as defined for GNU software:
+# http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
+# Inclusion of this module defines the following variables:
+# CMAKE_INSTALL_<dir> - destination for files of a given type
+# CMAKE_INSTALL_FULL_<dir> - corresponding absolute path
+# where <dir> is one of:
+# BINDIR - user executables (bin)
+# SBINDIR - system admin executables (sbin)
+# LIBEXECDIR - program executables (libexec)
+# SYSCONFDIR - read-only single-machine data (etc)
+# SHAREDSTATEDIR - modifiable architecture-independent data (com)
+# LOCALSTATEDIR - modifiable single-machine data (var)
+# LIBDIR - object code libraries (lib or lib64 or lib/<multiarch-tuple> on Debian)
+# INCLUDEDIR - C header files (include)
+# OLDINCLUDEDIR - C header files for non-gcc (/usr/include)
+# DATAROOTDIR - read-only architecture-independent data root (share)
+# DATADIR - read-only architecture-independent data (DATAROOTDIR)
+# INFODIR - info documentation (DATAROOTDIR/info)
+# LOCALEDIR - locale-dependent data (DATAROOTDIR/locale)
+# MANDIR - man documentation (DATAROOTDIR/man)
+# DOCDIR - documentation root (DATAROOTDIR/doc/PROJECT_NAME)
+# Each CMAKE_INSTALL_<dir> value may be passed to the DESTINATION options of
+# install() commands for the corresponding file type. If the includer does
+# not define a value the above-shown default will be used and the value will
+# appear in the cache for editing by the user.
+# Each CMAKE_INSTALL_FULL_<dir> value contains an absolute path constructed
+# from the corresponding destination by prepending (if necessary) the value
+# of CMAKE_INSTALL_PREFIX.
+
+#=============================================================================
+# Copyright 2011 Nikita Krupen'ko <krnekit@gmail.com>
+# Copyright 2011 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# Installation directories
+#
+if(NOT DEFINED CMAKE_INSTALL_BINDIR)
+ set(CMAKE_INSTALL_BINDIR "bin" CACHE PATH "user executables (bin)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_SBINDIR)
+ set(CMAKE_INSTALL_SBINDIR "sbin" CACHE PATH "system admin executables (sbin)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_LIBEXECDIR)
+ set(CMAKE_INSTALL_LIBEXECDIR "libexec" CACHE PATH "program executables (libexec)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_SYSCONFDIR)
+ set(CMAKE_INSTALL_SYSCONFDIR "etc" CACHE PATH "read-only single-machine data (etc)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_SHAREDSTATEDIR)
+ set(CMAKE_INSTALL_SHAREDSTATEDIR "com" CACHE PATH "modifiable architecture-independent data (com)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_LOCALSTATEDIR)
+ set(CMAKE_INSTALL_LOCALSTATEDIR "var" CACHE PATH "modifiable single-machine data (var)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
+ set(_LIBDIR_DEFAULT "lib")
+ # Override this default 'lib' with 'lib64' iff:
+ # - we are on Linux system but NOT cross-compiling
+ # - we are NOT on debian
+ # - we are on a 64 bits system
+ # reason is: amd64 ABI: http://www.x86-64.org/documentation/abi.pdf
+ # For Debian with multiarch, use 'lib/${CMAKE_LIBRARY_ARCHITECTURE}' if
+ # CMAKE_LIBRARY_ARCHITECTURE is set (which contains e.g. "i386-linux-gnu"
+ # See http://wiki.debian.org/Multiarch
+ if((CMAKE_SYSTEM_NAME MATCHES "Linux|kFreeBSD" OR CMAKE_SYSTEM_NAME STREQUAL "GNU")
+ AND NOT CMAKE_CROSSCOMPILING)
+ if (EXISTS "/etc/debian_version") # is this a debian system ?
+ if(CMAKE_LIBRARY_ARCHITECTURE)
+ set(_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
+ endif()
+ else() # not debian, rely on CMAKE_SIZEOF_VOID_P:
+ if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
+ message(AUTHOR_WARNING
+ "Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
+ "Please enable at least one language before including GNUInstallDirs.")
+ else()
+ if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
+ set(_LIBDIR_DEFAULT "lib64")
+ endif()
+ endif()
+ endif()
+ endif()
+ set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR)
+ set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE PATH "C header files (include)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_OLDINCLUDEDIR)
+ set(CMAKE_INSTALL_OLDINCLUDEDIR "/usr/include" CACHE PATH "C header files for non-gcc (/usr/include)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_DATAROOTDIR)
+ set(CMAKE_INSTALL_DATAROOTDIR "share" CACHE PATH "read-only architecture-independent data root (share)")
+endif()
+
+#-----------------------------------------------------------------------------
+# Values whose defaults are relative to DATAROOTDIR. Store empty values in
+# the cache and store the defaults in local variables if the cache values are
+# not set explicitly. This auto-updates the defaults as DATAROOTDIR changes.
+
+if(NOT CMAKE_INSTALL_DATADIR)
+ set(CMAKE_INSTALL_DATADIR "" CACHE PATH "read-only architecture-independent data (DATAROOTDIR)")
+ set(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}")
+endif()
+
+if(NOT CMAKE_INSTALL_INFODIR)
+ set(CMAKE_INSTALL_INFODIR "" CACHE PATH "info documentation (DATAROOTDIR/info)")
+ set(CMAKE_INSTALL_INFODIR "${CMAKE_INSTALL_DATAROOTDIR}/info")
+endif()
+
+if(NOT CMAKE_INSTALL_LOCALEDIR)
+ set(CMAKE_INSTALL_LOCALEDIR "" CACHE PATH "locale-dependent data (DATAROOTDIR/locale)")
+ set(CMAKE_INSTALL_LOCALEDIR "${CMAKE_INSTALL_DATAROOTDIR}/locale")
+endif()
+
+if(NOT CMAKE_INSTALL_MANDIR)
+ set(CMAKE_INSTALL_MANDIR "" CACHE PATH "man documentation (DATAROOTDIR/man)")
+ set(CMAKE_INSTALL_MANDIR "${CMAKE_INSTALL_DATAROOTDIR}/man")
+endif()
+
+if(NOT CMAKE_INSTALL_DOCDIR)
+ set(CMAKE_INSTALL_DOCDIR "" CACHE PATH "documentation root (DATAROOTDIR/doc/PROJECT_NAME)")
+ set(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}")
+endif()
+
+#-----------------------------------------------------------------------------
+
+mark_as_advanced(
+ CMAKE_INSTALL_BINDIR
+ CMAKE_INSTALL_SBINDIR
+ CMAKE_INSTALL_LIBEXECDIR
+ CMAKE_INSTALL_SYSCONFDIR
+ CMAKE_INSTALL_SHAREDSTATEDIR
+ CMAKE_INSTALL_LOCALSTATEDIR
+ CMAKE_INSTALL_LIBDIR
+ CMAKE_INSTALL_INCLUDEDIR
+ CMAKE_INSTALL_OLDINCLUDEDIR
+ CMAKE_INSTALL_DATAROOTDIR
+ CMAKE_INSTALL_DATADIR
+ CMAKE_INSTALL_INFODIR
+ CMAKE_INSTALL_LOCALEDIR
+ CMAKE_INSTALL_MANDIR
+ CMAKE_INSTALL_DOCDIR
+ )
+
+# Result directories
+#
+foreach(dir
+ BINDIR
+ SBINDIR
+ LIBEXECDIR
+ SYSCONFDIR
+ SHAREDSTATEDIR
+ LOCALSTATEDIR
+ LIBDIR
+ INCLUDEDIR
+ OLDINCLUDEDIR
+ DATAROOTDIR
+ DATADIR
+ INFODIR
+ LOCALEDIR
+ MANDIR
+ DOCDIR
+ )
+ if(NOT IS_ABSOLUTE ${CMAKE_INSTALL_${dir}})
+ set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}")
+ else()
+ set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_${dir}}")
+ endif()
+endforeach()
diff --git a/src/third_party/glm/cmake/glm.pc.in b/src/third_party/glm/cmake/glm.pc.in
new file mode 100644
index 0000000..fc5c7bb
--- /dev/null
+++ b/src/third_party/glm/cmake/glm.pc.in
@@ -0,0 +1,7 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+includedir=${prefix}/include
+
+Name: GLM
+Description: OpenGL Mathematics
+Version: @GLM_VERSION@
+Cflags: -I${includedir}
diff --git a/src/third_party/glm/cmake/glmBuildConfig.cmake.in b/src/third_party/glm/cmake/glmBuildConfig.cmake.in
new file mode 100644
index 0000000..1258dea
--- /dev/null
+++ b/src/third_party/glm/cmake/glmBuildConfig.cmake.in
@@ -0,0 +1,6 @@
+set(GLM_VERSION "@GLM_VERSION@")
+set(GLM_INCLUDE_DIRS "@CMAKE_CURRENT_SOURCE_DIR@")
+
+if (NOT CMAKE_VERSION VERSION_LESS "3.0")
+ include("${CMAKE_CURRENT_LIST_DIR}/glmTargets.cmake")
+endif()
diff --git a/src/third_party/glm/cmake/glmConfig.cmake.in b/src/third_party/glm/cmake/glmConfig.cmake.in
new file mode 100644
index 0000000..37d5ad8
--- /dev/null
+++ b/src/third_party/glm/cmake/glmConfig.cmake.in
@@ -0,0 +1,9 @@
+set(GLM_VERSION "@GLM_VERSION@")
+
+@PACKAGE_INIT@
+
+set_and_check(GLM_INCLUDE_DIRS "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@")
+
+if (NOT CMAKE_VERSION VERSION_LESS "3.0")
+ include("${CMAKE_CURRENT_LIST_DIR}/glmTargets.cmake")
+endif()
diff --git a/src/third_party/glm/copying.txt b/src/third_party/glm/copying.txt
new file mode 100644
index 0000000..7c20b4a
--- /dev/null
+++ b/src/third_party/glm/copying.txt
@@ -0,0 +1,54 @@
+================================================================================
+OpenGL Mathematics (GLM)
+--------------------------------------------------------------------------------
+GLM can be distributed and/or modified under the terms of either
+a) The Happy Bunny License, or b) the MIT License.
+
+================================================================================
+The Happy Bunny License (Modified MIT License)
+--------------------------------------------------------------------------------
+Copyright (c) 2005 - 2016 G-Truc Creation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Restrictions: By making use of the Software for military purposes, you choose
+to make a Bunny unhappy.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+================================================================================
+The MIT License
+--------------------------------------------------------------------------------
+Copyright (c) 2005 - 2016 G-Truc Creation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/third_party/glm/doc/api/a00001.html b/src/third_party/glm/doc/api/a00001.html
new file mode 100644
index 0000000..bf310c8
--- /dev/null
+++ b/src/third_party/glm/doc/api/a00001.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.10"/>
+<title>0.9.8: _features.hpp File Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="logo.png"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">0.9.8
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.10 -->
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div id="navrow2" class="tabs2">
+ <ul class="tablist">
+ <li><a href="files.html"><span>File List</span></a></li>
+ </ul>
+ </div>
+<div id="nav-path" class="navpath">
+ <ul>
+<li class="navelem"><a class="el" href="dir_275089585c7fc1b5fd5d7d42c69cb1da.html">D:</a></li><li class="navelem"><a class="el" href="dir_7b98f88bffbed4b390b5f8f520d9c08e.html">Source</a></li><li class="navelem"><a class="el" href="dir_1f76e953200861345293ade84ac7fb6c.html">G-Truc</a></li><li class="navelem"><a class="el" href="dir_e29b03b892e0e25920d021a614d4db9b.html">glm</a></li><li class="navelem"><a class="el" href="dir_5ce58d942b2d0776e17a9a58abc01e04.html">glm</a></li><li class="navelem"><a class="el" href="dir_e529a619cfdec1fa4c331fb042fd332f.html">detail</a></li> </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+ <div class="headertitle">
+<div class="title">_features.hpp File Reference</div> </div>
+</div><!--header-->
+<div class="contents">
+
+<p><a href="a00001_source.html">Go to the source code of this file.</a></p>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p><a class="el" href="a00156.html">GLM Core</a> </p>
+
+<p>Definition in file <a class="el" href="a00001_source.html">_features.hpp</a>.</p>
+</div></div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated by  <a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.10
+</small></address>
+</body>
+</html>
diff --git a/src/third_party/glm/doc/api/a00001_source.html b/src/third_party/glm/doc/api/a00001_source.html
new file mode 100644
index 0000000..2c98fae
--- /dev/null
+++ b/src/third_party/glm/doc/api/a00001_source.html
@@ -0,0 +1,457 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.10"/>
+<title>0.9.8: _features.hpp Source File</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="logo.png"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">0.9.8
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.10 -->
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div id="navrow2" class="tabs2">
+ <ul class="tablist">
+ <li><a href="files.html"><span>File List</span></a></li>
+ </ul>
+ </div>
+<div id="nav-path" class="navpath">
+ <ul>
+<li class="navelem"><a class="el" href="dir_275089585c7fc1b5fd5d7d42c69cb1da.html">D:</a></li><li class="navelem"><a class="el" href="dir_7b98f88bffbed4b390b5f8f520d9c08e.html">Source</a></li><li class="navelem"><a class="el" href="dir_1f76e953200861345293ade84ac7fb6c.html">G-Truc</a></li><li class="navelem"><a class="el" href="dir_e29b03b892e0e25920d021a614d4db9b.html">glm</a></li><li class="navelem"><a class="el" href="dir_5ce58d942b2d0776e17a9a58abc01e04.html">glm</a></li><li class="navelem"><a class="el" href="dir_e529a619cfdec1fa4c331fb042fd332f.html">detail</a></li> </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+ <div class="headertitle">
+<div class="title">_features.hpp</div> </div>
+</div><!--header-->
+<div class="contents">
+<a href="a00001.html">Go to the documentation of this file.</a><div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> </div>
+<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> <span class="preprocessor">#pragma once</span></div>
+<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> </div>
+<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> <span class="comment">// #define GLM_CXX98_EXCEPTIONS</span></div>
+<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> <span class="comment">// #define GLM_CXX98_RTTI</span></div>
+<div class="line"><a name="l00008"></a><span class="lineno"> 8</span> </div>
+<div class="line"><a name="l00009"></a><span class="lineno"> 9</span> <span class="comment">// #define GLM_CXX11_RVALUE_REFERENCES</span></div>
+<div class="line"><a name="l00010"></a><span class="lineno"> 10</span> <span class="comment">// Rvalue references - GCC 4.3</span></div>
+<div class="line"><a name="l00011"></a><span class="lineno"> 11</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html</span></div>
+<div class="line"><a name="l00012"></a><span class="lineno"> 12</span> </div>
+<div class="line"><a name="l00013"></a><span class="lineno"> 13</span> <span class="comment">// GLM_CXX11_TRAILING_RETURN</span></div>
+<div class="line"><a name="l00014"></a><span class="lineno"> 14</span> <span class="comment">// Rvalue references for *this - GCC not supported</span></div>
+<div class="line"><a name="l00015"></a><span class="lineno"> 15</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2439.htm</span></div>
+<div class="line"><a name="l00016"></a><span class="lineno"> 16</span> </div>
+<div class="line"><a name="l00017"></a><span class="lineno"> 17</span> <span class="comment">// GLM_CXX11_NONSTATIC_MEMBER_INIT</span></div>
+<div class="line"><a name="l00018"></a><span class="lineno"> 18</span> <span class="comment">// Initialization of class objects by rvalues - GCC any</span></div>
+<div class="line"><a name="l00019"></a><span class="lineno"> 19</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1610.html</span></div>
+<div class="line"><a name="l00020"></a><span class="lineno"> 20</span> </div>
+<div class="line"><a name="l00021"></a><span class="lineno"> 21</span> <span class="comment">// GLM_CXX11_NONSTATIC_MEMBER_INIT</span></div>
+<div class="line"><a name="l00022"></a><span class="lineno"> 22</span> <span class="comment">// Non-static data member initializers - GCC 4.7</span></div>
+<div class="line"><a name="l00023"></a><span class="lineno"> 23</span> <span class="comment">// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2756.htm</span></div>
+<div class="line"><a name="l00024"></a><span class="lineno"> 24</span> </div>
+<div class="line"><a name="l00025"></a><span class="lineno"> 25</span> <span class="comment">// #define GLM_CXX11_VARIADIC_TEMPLATE</span></div>
+<div class="line"><a name="l00026"></a><span class="lineno"> 26</span> <span class="comment">// Variadic templates - GCC 4.3</span></div>
+<div class="line"><a name="l00027"></a><span class="lineno"> 27</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdf</span></div>
+<div class="line"><a name="l00028"></a><span class="lineno"> 28</span> </div>
+<div class="line"><a name="l00029"></a><span class="lineno"> 29</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00030"></a><span class="lineno"> 30</span> <span class="comment">// Extending variadic template template parameters - GCC 4.4</span></div>
+<div class="line"><a name="l00031"></a><span class="lineno"> 31</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf</span></div>
+<div class="line"><a name="l00032"></a><span class="lineno"> 32</span> </div>
+<div class="line"><a name="l00033"></a><span class="lineno"> 33</span> <span class="comment">// #define GLM_CXX11_GENERALIZED_INITIALIZERS</span></div>
+<div class="line"><a name="l00034"></a><span class="lineno"> 34</span> <span class="comment">// Initializer lists - GCC 4.4</span></div>
+<div class="line"><a name="l00035"></a><span class="lineno"> 35</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm</span></div>
+<div class="line"><a name="l00036"></a><span class="lineno"> 36</span> </div>
+<div class="line"><a name="l00037"></a><span class="lineno"> 37</span> <span class="comment">// #define GLM_CXX11_STATIC_ASSERT </span></div>
+<div class="line"><a name="l00038"></a><span class="lineno"> 38</span> <span class="comment">// Static assertions - GCC 4.3</span></div>
+<div class="line"><a name="l00039"></a><span class="lineno"> 39</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1720.html</span></div>
+<div class="line"><a name="l00040"></a><span class="lineno"> 40</span> </div>
+<div class="line"><a name="l00041"></a><span class="lineno"> 41</span> <span class="comment">// #define GLM_CXX11_AUTO_TYPE</span></div>
+<div class="line"><a name="l00042"></a><span class="lineno"> 42</span> <span class="comment">// auto-typed variables - GCC 4.4</span></div>
+<div class="line"><a name="l00043"></a><span class="lineno"> 43</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1984.pdf</span></div>
+<div class="line"><a name="l00044"></a><span class="lineno"> 44</span> </div>
+<div class="line"><a name="l00045"></a><span class="lineno"> 45</span> <span class="comment">// #define GLM_CXX11_AUTO_TYPE</span></div>
+<div class="line"><a name="l00046"></a><span class="lineno"> 46</span> <span class="comment">// Multi-declarator auto - GCC 4.4</span></div>
+<div class="line"><a name="l00047"></a><span class="lineno"> 47</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1737.pdf</span></div>
+<div class="line"><a name="l00048"></a><span class="lineno"> 48</span> </div>
+<div class="line"><a name="l00049"></a><span class="lineno"> 49</span> <span class="comment">// #define GLM_CXX11_AUTO_TYPE</span></div>
+<div class="line"><a name="l00050"></a><span class="lineno"> 50</span> <span class="comment">// Removal of auto as a storage-class specifier - GCC 4.4</span></div>
+<div class="line"><a name="l00051"></a><span class="lineno"> 51</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2546.htm</span></div>
+<div class="line"><a name="l00052"></a><span class="lineno"> 52</span> </div>
+<div class="line"><a name="l00053"></a><span class="lineno"> 53</span> <span class="comment">// #define GLM_CXX11_AUTO_TYPE</span></div>
+<div class="line"><a name="l00054"></a><span class="lineno"> 54</span> <span class="comment">// New function declarator syntax - GCC 4.4</span></div>
+<div class="line"><a name="l00055"></a><span class="lineno"> 55</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2541.htm</span></div>
+<div class="line"><a name="l00056"></a><span class="lineno"> 56</span> </div>
+<div class="line"><a name="l00057"></a><span class="lineno"> 57</span> <span class="comment">// #define GLM_CXX11_LAMBDAS</span></div>
+<div class="line"><a name="l00058"></a><span class="lineno"> 58</span> <span class="comment">// New wording for C++0x lambdas - GCC 4.5</span></div>
+<div class="line"><a name="l00059"></a><span class="lineno"> 59</span> <span class="comment">// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2927.pdf</span></div>
+<div class="line"><a name="l00060"></a><span class="lineno"> 60</span> </div>
+<div class="line"><a name="l00061"></a><span class="lineno"> 61</span> <span class="comment">// #define GLM_CXX11_DECLTYPE</span></div>
+<div class="line"><a name="l00062"></a><span class="lineno"> 62</span> <span class="comment">// Declared type of an expression - GCC 4.3</span></div>
+<div class="line"><a name="l00063"></a><span class="lineno"> 63</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2343.pdf</span></div>
+<div class="line"><a name="l00064"></a><span class="lineno"> 64</span> </div>
+<div class="line"><a name="l00065"></a><span class="lineno"> 65</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00066"></a><span class="lineno"> 66</span> <span class="comment">// Right angle brackets - GCC 4.3</span></div>
+<div class="line"><a name="l00067"></a><span class="lineno"> 67</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html</span></div>
+<div class="line"><a name="l00068"></a><span class="lineno"> 68</span> </div>
+<div class="line"><a name="l00069"></a><span class="lineno"> 69</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00070"></a><span class="lineno"> 70</span> <span class="comment">// Default template arguments for function templates DR226 GCC 4.3</span></div>
+<div class="line"><a name="l00071"></a><span class="lineno"> 71</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#226</span></div>
+<div class="line"><a name="l00072"></a><span class="lineno"> 72</span> </div>
+<div class="line"><a name="l00073"></a><span class="lineno"> 73</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00074"></a><span class="lineno"> 74</span> <span class="comment">// Solving the SFINAE problem for expressions DR339 GCC 4.4</span></div>
+<div class="line"><a name="l00075"></a><span class="lineno"> 75</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html</span></div>
+<div class="line"><a name="l00076"></a><span class="lineno"> 76</span> </div>
+<div class="line"><a name="l00077"></a><span class="lineno"> 77</span> <span class="comment">// #define GLM_CXX11_ALIAS_TEMPLATE</span></div>
+<div class="line"><a name="l00078"></a><span class="lineno"> 78</span> <span class="comment">// Template aliases N2258 GCC 4.7</span></div>
+<div class="line"><a name="l00079"></a><span class="lineno"> 79</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf</span></div>
+<div class="line"><a name="l00080"></a><span class="lineno"> 80</span> </div>
+<div class="line"><a name="l00081"></a><span class="lineno"> 81</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00082"></a><span class="lineno"> 82</span> <span class="comment">// Extern templates N1987 Yes</span></div>
+<div class="line"><a name="l00083"></a><span class="lineno"> 83</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1987.htm</span></div>
+<div class="line"><a name="l00084"></a><span class="lineno"> 84</span> </div>
+<div class="line"><a name="l00085"></a><span class="lineno"> 85</span> <span class="comment">// #define GLM_CXX11_NULLPTR</span></div>
+<div class="line"><a name="l00086"></a><span class="lineno"> 86</span> <span class="comment">// Null pointer constant N2431 GCC 4.6</span></div>
+<div class="line"><a name="l00087"></a><span class="lineno"> 87</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf</span></div>
+<div class="line"><a name="l00088"></a><span class="lineno"> 88</span> </div>
+<div class="line"><a name="l00089"></a><span class="lineno"> 89</span> <span class="comment">// #define GLM_CXX11_STRONG_ENUMS</span></div>
+<div class="line"><a name="l00090"></a><span class="lineno"> 90</span> <span class="comment">// Strongly-typed enums N2347 GCC 4.4</span></div>
+<div class="line"><a name="l00091"></a><span class="lineno"> 91</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf</span></div>
+<div class="line"><a name="l00092"></a><span class="lineno"> 92</span> </div>
+<div class="line"><a name="l00093"></a><span class="lineno"> 93</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00094"></a><span class="lineno"> 94</span> <span class="comment">// Forward declarations for enums N2764 GCC 4.6</span></div>
+<div class="line"><a name="l00095"></a><span class="lineno"> 95</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2764.pdf</span></div>
+<div class="line"><a name="l00096"></a><span class="lineno"> 96</span> </div>
+<div class="line"><a name="l00097"></a><span class="lineno"> 97</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00098"></a><span class="lineno"> 98</span> <span class="comment">// Generalized attributes N2761 GCC 4.8</span></div>
+<div class="line"><a name="l00099"></a><span class="lineno"> 99</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2761.pdf</span></div>
+<div class="line"><a name="l00100"></a><span class="lineno"> 100</span> </div>
+<div class="line"><a name="l00101"></a><span class="lineno"> 101</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00102"></a><span class="lineno"> 102</span> <span class="comment">// Generalized constant expressions N2235 GCC 4.6</span></div>
+<div class="line"><a name="l00103"></a><span class="lineno"> 103</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf</span></div>
+<div class="line"><a name="l00104"></a><span class="lineno"> 104</span> </div>
+<div class="line"><a name="l00105"></a><span class="lineno"> 105</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00106"></a><span class="lineno"> 106</span> <span class="comment">// Alignment support N2341 GCC 4.8</span></div>
+<div class="line"><a name="l00107"></a><span class="lineno"> 107</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf</span></div>
+<div class="line"><a name="l00108"></a><span class="lineno"> 108</span> </div>
+<div class="line"><a name="l00109"></a><span class="lineno"> 109</span> <span class="comment">// #define GLM_CXX11_DELEGATING_CONSTRUCTORS</span></div>
+<div class="line"><a name="l00110"></a><span class="lineno"> 110</span> <span class="comment">// Delegating constructors N1986 GCC 4.7</span></div>
+<div class="line"><a name="l00111"></a><span class="lineno"> 111</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf</span></div>
+<div class="line"><a name="l00112"></a><span class="lineno"> 112</span> </div>
+<div class="line"><a name="l00113"></a><span class="lineno"> 113</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00114"></a><span class="lineno"> 114</span> <span class="comment">// Inheriting constructors N2540 GCC 4.8</span></div>
+<div class="line"><a name="l00115"></a><span class="lineno"> 115</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm</span></div>
+<div class="line"><a name="l00116"></a><span class="lineno"> 116</span> </div>
+<div class="line"><a name="l00117"></a><span class="lineno"> 117</span> <span class="comment">// #define GLM_CXX11_EXPLICIT_CONVERSIONS</span></div>
+<div class="line"><a name="l00118"></a><span class="lineno"> 118</span> <span class="comment">// Explicit conversion operators N2437 GCC 4.5</span></div>
+<div class="line"><a name="l00119"></a><span class="lineno"> 119</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf</span></div>
+<div class="line"><a name="l00120"></a><span class="lineno"> 120</span> </div>
+<div class="line"><a name="l00121"></a><span class="lineno"> 121</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00122"></a><span class="lineno"> 122</span> <span class="comment">// New character types N2249 GCC 4.4</span></div>
+<div class="line"><a name="l00123"></a><span class="lineno"> 123</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2249.html</span></div>
+<div class="line"><a name="l00124"></a><span class="lineno"> 124</span> </div>
+<div class="line"><a name="l00125"></a><span class="lineno"> 125</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00126"></a><span class="lineno"> 126</span> <span class="comment">// Unicode string literals N2442 GCC 4.5</span></div>
+<div class="line"><a name="l00127"></a><span class="lineno"> 127</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm</span></div>
+<div class="line"><a name="l00128"></a><span class="lineno"> 128</span> </div>
+<div class="line"><a name="l00129"></a><span class="lineno"> 129</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00130"></a><span class="lineno"> 130</span> <span class="comment">// Raw string literals N2442 GCC 4.5</span></div>
+<div class="line"><a name="l00131"></a><span class="lineno"> 131</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm</span></div>
+<div class="line"><a name="l00132"></a><span class="lineno"> 132</span> </div>
+<div class="line"><a name="l00133"></a><span class="lineno"> 133</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00134"></a><span class="lineno"> 134</span> <span class="comment">// Universal character name literals N2170 GCC 4.5</span></div>
+<div class="line"><a name="l00135"></a><span class="lineno"> 135</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2170.html</span></div>
+<div class="line"><a name="l00136"></a><span class="lineno"> 136</span> </div>
+<div class="line"><a name="l00137"></a><span class="lineno"> 137</span> <span class="comment">// #define GLM_CXX11_USER_LITERALS</span></div>
+<div class="line"><a name="l00138"></a><span class="lineno"> 138</span> <span class="comment">// User-defined literals N2765 GCC 4.7</span></div>
+<div class="line"><a name="l00139"></a><span class="lineno"> 139</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2765.pdf</span></div>
+<div class="line"><a name="l00140"></a><span class="lineno"> 140</span> </div>
+<div class="line"><a name="l00141"></a><span class="lineno"> 141</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00142"></a><span class="lineno"> 142</span> <span class="comment">// Standard Layout Types N2342 GCC 4.5</span></div>
+<div class="line"><a name="l00143"></a><span class="lineno"> 143</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm</span></div>
+<div class="line"><a name="l00144"></a><span class="lineno"> 144</span> </div>
+<div class="line"><a name="l00145"></a><span class="lineno"> 145</span> <span class="comment">// #define GLM_CXX11_DEFAULTED_FUNCTIONS</span></div>
+<div class="line"><a name="l00146"></a><span class="lineno"> 146</span> <span class="comment">// #define GLM_CXX11_DELETED_FUNCTIONS</span></div>
+<div class="line"><a name="l00147"></a><span class="lineno"> 147</span> <span class="comment">// Defaulted and deleted functions N2346 GCC 4.4</span></div>
+<div class="line"><a name="l00148"></a><span class="lineno"> 148</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm</span></div>
+<div class="line"><a name="l00149"></a><span class="lineno"> 149</span> </div>
+<div class="line"><a name="l00150"></a><span class="lineno"> 150</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00151"></a><span class="lineno"> 151</span> <span class="comment">// Extended friend declarations N1791 GCC 4.7</span></div>
+<div class="line"><a name="l00152"></a><span class="lineno"> 152</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1791.pdf</span></div>
+<div class="line"><a name="l00153"></a><span class="lineno"> 153</span> </div>
+<div class="line"><a name="l00154"></a><span class="lineno"> 154</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00155"></a><span class="lineno"> 155</span> <span class="comment">// Extending sizeof N2253 GCC 4.4</span></div>
+<div class="line"><a name="l00156"></a><span class="lineno"> 156</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2253.html</span></div>
+<div class="line"><a name="l00157"></a><span class="lineno"> 157</span> </div>
+<div class="line"><a name="l00158"></a><span class="lineno"> 158</span> <span class="comment">// #define GLM_CXX11_INLINE_NAMESPACES</span></div>
+<div class="line"><a name="l00159"></a><span class="lineno"> 159</span> <span class="comment">// Inline namespaces N2535 GCC 4.4</span></div>
+<div class="line"><a name="l00160"></a><span class="lineno"> 160</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2535.htm</span></div>
+<div class="line"><a name="l00161"></a><span class="lineno"> 161</span> </div>
+<div class="line"><a name="l00162"></a><span class="lineno"> 162</span> <span class="comment">// #define GLM_CXX11_UNRESTRICTED_UNIONS</span></div>
+<div class="line"><a name="l00163"></a><span class="lineno"> 163</span> <span class="comment">// Unrestricted unions N2544 GCC 4.6</span></div>
+<div class="line"><a name="l00164"></a><span class="lineno"> 164</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf</span></div>
+<div class="line"><a name="l00165"></a><span class="lineno"> 165</span> </div>
+<div class="line"><a name="l00166"></a><span class="lineno"> 166</span> <span class="comment">// #define GLM_CXX11_LOCAL_TYPE_TEMPLATE_ARGS</span></div>
+<div class="line"><a name="l00167"></a><span class="lineno"> 167</span> <span class="comment">// Local and unnamed types as template arguments N2657 GCC 4.5</span></div>
+<div class="line"><a name="l00168"></a><span class="lineno"> 168</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm</span></div>
+<div class="line"><a name="l00169"></a><span class="lineno"> 169</span> </div>
+<div class="line"><a name="l00170"></a><span class="lineno"> 170</span> <span class="comment">// #define GLM_CXX11_RANGE_FOR</span></div>
+<div class="line"><a name="l00171"></a><span class="lineno"> 171</span> <span class="comment">// Range-based for N2930 GCC 4.6</span></div>
+<div class="line"><a name="l00172"></a><span class="lineno"> 172</span> <span class="comment">// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2930.html</span></div>
+<div class="line"><a name="l00173"></a><span class="lineno"> 173</span> </div>
+<div class="line"><a name="l00174"></a><span class="lineno"> 174</span> <span class="comment">// #define GLM_CXX11_OVERRIDE_CONTROL</span></div>
+<div class="line"><a name="l00175"></a><span class="lineno"> 175</span> <span class="comment">// Explicit virtual overrides N2928 N3206 N3272 GCC 4.7</span></div>
+<div class="line"><a name="l00176"></a><span class="lineno"> 176</span> <span class="comment">// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm</span></div>
+<div class="line"><a name="l00177"></a><span class="lineno"> 177</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3206.htm</span></div>
+<div class="line"><a name="l00178"></a><span class="lineno"> 178</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3272.htm</span></div>
+<div class="line"><a name="l00179"></a><span class="lineno"> 179</span> </div>
+<div class="line"><a name="l00180"></a><span class="lineno"> 180</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00181"></a><span class="lineno"> 181</span> <span class="comment">// Minimal support for garbage collection and reachability-based leak detection N2670 No</span></div>
+<div class="line"><a name="l00182"></a><span class="lineno"> 182</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2670.htm</span></div>
+<div class="line"><a name="l00183"></a><span class="lineno"> 183</span> </div>
+<div class="line"><a name="l00184"></a><span class="lineno"> 184</span> <span class="comment">// #define GLM_CXX11_NOEXCEPT</span></div>
+<div class="line"><a name="l00185"></a><span class="lineno"> 185</span> <span class="comment">// Allowing move constructors to throw [noexcept] N3050 GCC 4.6 (core language only)</span></div>
+<div class="line"><a name="l00186"></a><span class="lineno"> 186</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3050.html</span></div>
+<div class="line"><a name="l00187"></a><span class="lineno"> 187</span> </div>
+<div class="line"><a name="l00188"></a><span class="lineno"> 188</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00189"></a><span class="lineno"> 189</span> <span class="comment">// Defining move special member functions N3053 GCC 4.6</span></div>
+<div class="line"><a name="l00190"></a><span class="lineno"> 190</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3053.html</span></div>
+<div class="line"><a name="l00191"></a><span class="lineno"> 191</span> </div>
+<div class="line"><a name="l00192"></a><span class="lineno"> 192</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00193"></a><span class="lineno"> 193</span> <span class="comment">// Sequence points N2239 Yes</span></div>
+<div class="line"><a name="l00194"></a><span class="lineno"> 194</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2239.html</span></div>
+<div class="line"><a name="l00195"></a><span class="lineno"> 195</span> </div>
+<div class="line"><a name="l00196"></a><span class="lineno"> 196</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00197"></a><span class="lineno"> 197</span> <span class="comment">// Atomic operations N2427 GCC 4.4</span></div>
+<div class="line"><a name="l00198"></a><span class="lineno"> 198</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2239.html</span></div>
+<div class="line"><a name="l00199"></a><span class="lineno"> 199</span> </div>
+<div class="line"><a name="l00200"></a><span class="lineno"> 200</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00201"></a><span class="lineno"> 201</span> <span class="comment">// Strong Compare and Exchange N2748 GCC 4.5</span></div>
+<div class="line"><a name="l00202"></a><span class="lineno"> 202</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html</span></div>
+<div class="line"><a name="l00203"></a><span class="lineno"> 203</span> </div>
+<div class="line"><a name="l00204"></a><span class="lineno"> 204</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00205"></a><span class="lineno"> 205</span> <span class="comment">// Bidirectional Fences N2752 GCC 4.8</span></div>
+<div class="line"><a name="l00206"></a><span class="lineno"> 206</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2752.htm</span></div>
+<div class="line"><a name="l00207"></a><span class="lineno"> 207</span> </div>
+<div class="line"><a name="l00208"></a><span class="lineno"> 208</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00209"></a><span class="lineno"> 209</span> <span class="comment">// Memory model N2429 GCC 4.8</span></div>
+<div class="line"><a name="l00210"></a><span class="lineno"> 210</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2429.htm</span></div>
+<div class="line"><a name="l00211"></a><span class="lineno"> 211</span> </div>
+<div class="line"><a name="l00212"></a><span class="lineno"> 212</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00213"></a><span class="lineno"> 213</span> <span class="comment">// Data-dependency ordering: atomics and memory model N2664 GCC 4.4</span></div>
+<div class="line"><a name="l00214"></a><span class="lineno"> 214</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2664.htm</span></div>
+<div class="line"><a name="l00215"></a><span class="lineno"> 215</span> </div>
+<div class="line"><a name="l00216"></a><span class="lineno"> 216</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00217"></a><span class="lineno"> 217</span> <span class="comment">// Propagating exceptions N2179 GCC 4.4</span></div>
+<div class="line"><a name="l00218"></a><span class="lineno"> 218</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2179.html</span></div>
+<div class="line"><a name="l00219"></a><span class="lineno"> 219</span> </div>
+<div class="line"><a name="l00220"></a><span class="lineno"> 220</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00221"></a><span class="lineno"> 221</span> <span class="comment">// Abandoning a process and at_quick_exit N2440 GCC 4.8</span></div>
+<div class="line"><a name="l00222"></a><span class="lineno"> 222</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2440.htm</span></div>
+<div class="line"><a name="l00223"></a><span class="lineno"> 223</span> </div>
+<div class="line"><a name="l00224"></a><span class="lineno"> 224</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00225"></a><span class="lineno"> 225</span> <span class="comment">// Allow atomics use in signal handlers N2547 Yes</span></div>
+<div class="line"><a name="l00226"></a><span class="lineno"> 226</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2547.htm</span></div>
+<div class="line"><a name="l00227"></a><span class="lineno"> 227</span> </div>
+<div class="line"><a name="l00228"></a><span class="lineno"> 228</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00229"></a><span class="lineno"> 229</span> <span class="comment">// Thread-local storage N2659 GCC 4.8</span></div>
+<div class="line"><a name="l00230"></a><span class="lineno"> 230</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2659.htm</span></div>
+<div class="line"><a name="l00231"></a><span class="lineno"> 231</span> </div>
+<div class="line"><a name="l00232"></a><span class="lineno"> 232</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00233"></a><span class="lineno"> 233</span> <span class="comment">// Dynamic initialization and destruction with concurrency N2660 GCC 4.3</span></div>
+<div class="line"><a name="l00234"></a><span class="lineno"> 234</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm</span></div>
+<div class="line"><a name="l00235"></a><span class="lineno"> 235</span> </div>
+<div class="line"><a name="l00236"></a><span class="lineno"> 236</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00237"></a><span class="lineno"> 237</span> <span class="comment">// __func__ predefined identifier N2340 GCC 4.3</span></div>
+<div class="line"><a name="l00238"></a><span class="lineno"> 238</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2340.htm</span></div>
+<div class="line"><a name="l00239"></a><span class="lineno"> 239</span> </div>
+<div class="line"><a name="l00240"></a><span class="lineno"> 240</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00241"></a><span class="lineno"> 241</span> <span class="comment">// C99 preprocessor N1653 GCC 4.3</span></div>
+<div class="line"><a name="l00242"></a><span class="lineno"> 242</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1653.htm</span></div>
+<div class="line"><a name="l00243"></a><span class="lineno"> 243</span> </div>
+<div class="line"><a name="l00244"></a><span class="lineno"> 244</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00245"></a><span class="lineno"> 245</span> <span class="comment">// long long N1811 GCC 4.3</span></div>
+<div class="line"><a name="l00246"></a><span class="lineno"> 246</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1811.pdf</span></div>
+<div class="line"><a name="l00247"></a><span class="lineno"> 247</span> </div>
+<div class="line"><a name="l00248"></a><span class="lineno"> 248</span> <span class="comment">// </span></div>
+<div class="line"><a name="l00249"></a><span class="lineno"> 249</span> <span class="comment">// Extended integral types N1988 Yes</span></div>
+<div class="line"><a name="l00250"></a><span class="lineno"> 250</span> <span class="comment">// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1988.pdf</span></div>
+<div class="line"><a name="l00251"></a><span class="lineno"> 251</span> </div>
+<div class="line"><a name="l00252"></a><span class="lineno"> 252</span> <span class="preprocessor">#if(GLM_COMPILER & GLM_COMPILER_GCC)</span></div>
+<div class="line"><a name="l00253"></a><span class="lineno"> 253</span> </div>
+<div class="line"><a name="l00254"></a><span class="lineno"> 254</span> <span class="preprocessor"># if(GLM_COMPILER >= GLM_COMPILER_GCC43)</span></div>
+<div class="line"><a name="l00255"></a><span class="lineno"> 255</span> <span class="preprocessor"># define GLM_CXX11_STATIC_ASSERT</span></div>
+<div class="line"><a name="l00256"></a><span class="lineno"> 256</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00257"></a><span class="lineno"> 257</span> </div>
+<div class="line"><a name="l00258"></a><span class="lineno"> 258</span> <span class="preprocessor">#elif(GLM_COMPILER & GLM_COMPILER_CLANG)</span></div>
+<div class="line"><a name="l00259"></a><span class="lineno"> 259</span> <span class="preprocessor"># if(__has_feature(cxx_exceptions))</span></div>
+<div class="line"><a name="l00260"></a><span class="lineno"> 260</span> <span class="preprocessor"># define GLM_CXX98_EXCEPTIONS</span></div>
+<div class="line"><a name="l00261"></a><span class="lineno"> 261</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00262"></a><span class="lineno"> 262</span> </div>
+<div class="line"><a name="l00263"></a><span class="lineno"> 263</span> <span class="preprocessor"># if(__has_feature(cxx_rtti))</span></div>
+<div class="line"><a name="l00264"></a><span class="lineno"> 264</span> <span class="preprocessor"># define GLM_CXX98_RTTI</span></div>
+<div class="line"><a name="l00265"></a><span class="lineno"> 265</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00266"></a><span class="lineno"> 266</span> </div>
+<div class="line"><a name="l00267"></a><span class="lineno"> 267</span> <span class="preprocessor"># if(__has_feature(cxx_access_control_sfinae))</span></div>
+<div class="line"><a name="l00268"></a><span class="lineno"> 268</span> <span class="preprocessor"># define GLM_CXX11_ACCESS_CONTROL_SFINAE</span></div>
+<div class="line"><a name="l00269"></a><span class="lineno"> 269</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00270"></a><span class="lineno"> 270</span> </div>
+<div class="line"><a name="l00271"></a><span class="lineno"> 271</span> <span class="preprocessor"># if(__has_feature(cxx_alias_templates))</span></div>
+<div class="line"><a name="l00272"></a><span class="lineno"> 272</span> <span class="preprocessor"># define GLM_CXX11_ALIAS_TEMPLATE</span></div>
+<div class="line"><a name="l00273"></a><span class="lineno"> 273</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00274"></a><span class="lineno"> 274</span> </div>
+<div class="line"><a name="l00275"></a><span class="lineno"> 275</span> <span class="preprocessor"># if(__has_feature(cxx_alignas))</span></div>
+<div class="line"><a name="l00276"></a><span class="lineno"> 276</span> <span class="preprocessor"># define GLM_CXX11_ALIGNAS</span></div>
+<div class="line"><a name="l00277"></a><span class="lineno"> 277</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00278"></a><span class="lineno"> 278</span> </div>
+<div class="line"><a name="l00279"></a><span class="lineno"> 279</span> <span class="preprocessor"># if(__has_feature(cxx_attributes))</span></div>
+<div class="line"><a name="l00280"></a><span class="lineno"> 280</span> <span class="preprocessor"># define GLM_CXX11_ATTRIBUTES</span></div>
+<div class="line"><a name="l00281"></a><span class="lineno"> 281</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00282"></a><span class="lineno"> 282</span> </div>
+<div class="line"><a name="l00283"></a><span class="lineno"> 283</span> <span class="preprocessor"># if(__has_feature(cxx_constexpr))</span></div>
+<div class="line"><a name="l00284"></a><span class="lineno"> 284</span> <span class="preprocessor"># define GLM_CXX11_CONSTEXPR</span></div>
+<div class="line"><a name="l00285"></a><span class="lineno"> 285</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00286"></a><span class="lineno"> 286</span> </div>
+<div class="line"><a name="l00287"></a><span class="lineno"> 287</span> <span class="preprocessor"># if(__has_feature(cxx_decltype))</span></div>
+<div class="line"><a name="l00288"></a><span class="lineno"> 288</span> <span class="preprocessor"># define GLM_CXX11_DECLTYPE</span></div>
+<div class="line"><a name="l00289"></a><span class="lineno"> 289</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00290"></a><span class="lineno"> 290</span> </div>
+<div class="line"><a name="l00291"></a><span class="lineno"> 291</span> <span class="preprocessor"># if(__has_feature(cxx_default_function_template_args))</span></div>
+<div class="line"><a name="l00292"></a><span class="lineno"> 292</span> <span class="preprocessor"># define GLM_CXX11_DEFAULT_FUNCTION_TEMPLATE_ARGS</span></div>
+<div class="line"><a name="l00293"></a><span class="lineno"> 293</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00294"></a><span class="lineno"> 294</span> </div>
+<div class="line"><a name="l00295"></a><span class="lineno"> 295</span> <span class="preprocessor"># if(__has_feature(cxx_defaulted_functions))</span></div>
+<div class="line"><a name="l00296"></a><span class="lineno"> 296</span> <span class="preprocessor"># define GLM_CXX11_DEFAULTED_FUNCTIONS</span></div>
+<div class="line"><a name="l00297"></a><span class="lineno"> 297</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00298"></a><span class="lineno"> 298</span> </div>
+<div class="line"><a name="l00299"></a><span class="lineno"> 299</span> <span class="preprocessor"># if(__has_feature(cxx_delegating_constructors))</span></div>
+<div class="line"><a name="l00300"></a><span class="lineno"> 300</span> <span class="preprocessor"># define GLM_CXX11_DELEGATING_CONSTRUCTORS</span></div>
+<div class="line"><a name="l00301"></a><span class="lineno"> 301</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00302"></a><span class="lineno"> 302</span> </div>
+<div class="line"><a name="l00303"></a><span class="lineno"> 303</span> <span class="preprocessor"># if(__has_feature(cxx_deleted_functions))</span></div>
+<div class="line"><a name="l00304"></a><span class="lineno"> 304</span> <span class="preprocessor"># define GLM_CXX11_DELETED_FUNCTIONS</span></div>
+<div class="line"><a name="l00305"></a><span class="lineno"> 305</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00306"></a><span class="lineno"> 306</span> </div>
+<div class="line"><a name="l00307"></a><span class="lineno"> 307</span> <span class="preprocessor"># if(__has_feature(cxx_explicit_conversions))</span></div>
+<div class="line"><a name="l00308"></a><span class="lineno"> 308</span> <span class="preprocessor"># define GLM_CXX11_EXPLICIT_CONVERSIONS</span></div>
+<div class="line"><a name="l00309"></a><span class="lineno"> 309</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00310"></a><span class="lineno"> 310</span> </div>
+<div class="line"><a name="l00311"></a><span class="lineno"> 311</span> <span class="preprocessor"># if(__has_feature(cxx_generalized_initializers))</span></div>
+<div class="line"><a name="l00312"></a><span class="lineno"> 312</span> <span class="preprocessor"># define GLM_CXX11_GENERALIZED_INITIALIZERS</span></div>
+<div class="line"><a name="l00313"></a><span class="lineno"> 313</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00314"></a><span class="lineno"> 314</span> </div>
+<div class="line"><a name="l00315"></a><span class="lineno"> 315</span> <span class="preprocessor"># if(__has_feature(cxx_implicit_moves))</span></div>
+<div class="line"><a name="l00316"></a><span class="lineno"> 316</span> <span class="preprocessor"># define GLM_CXX11_IMPLICIT_MOVES</span></div>
+<div class="line"><a name="l00317"></a><span class="lineno"> 317</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00318"></a><span class="lineno"> 318</span> </div>
+<div class="line"><a name="l00319"></a><span class="lineno"> 319</span> <span class="preprocessor"># if(__has_feature(cxx_inheriting_constructors))</span></div>
+<div class="line"><a name="l00320"></a><span class="lineno"> 320</span> <span class="preprocessor"># define GLM_CXX11_INHERITING_CONSTRUCTORS</span></div>
+<div class="line"><a name="l00321"></a><span class="lineno"> 321</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00322"></a><span class="lineno"> 322</span> </div>
+<div class="line"><a name="l00323"></a><span class="lineno"> 323</span> <span class="preprocessor"># if(__has_feature(cxx_inline_namespaces))</span></div>
+<div class="line"><a name="l00324"></a><span class="lineno"> 324</span> <span class="preprocessor"># define GLM_CXX11_INLINE_NAMESPACES</span></div>
+<div class="line"><a name="l00325"></a><span class="lineno"> 325</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00326"></a><span class="lineno"> 326</span> </div>
+<div class="line"><a name="l00327"></a><span class="lineno"> 327</span> <span class="preprocessor"># if(__has_feature(cxx_lambdas))</span></div>
+<div class="line"><a name="l00328"></a><span class="lineno"> 328</span> <span class="preprocessor"># define GLM_CXX11_LAMBDAS</span></div>
+<div class="line"><a name="l00329"></a><span class="lineno"> 329</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00330"></a><span class="lineno"> 330</span> </div>
+<div class="line"><a name="l00331"></a><span class="lineno"> 331</span> <span class="preprocessor"># if(__has_feature(cxx_local_type_template_args))</span></div>
+<div class="line"><a name="l00332"></a><span class="lineno"> 332</span> <span class="preprocessor"># define GLM_CXX11_LOCAL_TYPE_TEMPLATE_ARGS</span></div>
+<div class="line"><a name="l00333"></a><span class="lineno"> 333</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00334"></a><span class="lineno"> 334</span> </div>
+<div class="line"><a name="l00335"></a><span class="lineno"> 335</span> <span class="preprocessor"># if(__has_feature(cxx_noexcept))</span></div>
+<div class="line"><a name="l00336"></a><span class="lineno"> 336</span> <span class="preprocessor"># define GLM_CXX11_NOEXCEPT</span></div>
+<div class="line"><a name="l00337"></a><span class="lineno"> 337</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00338"></a><span class="lineno"> 338</span> </div>
+<div class="line"><a name="l00339"></a><span class="lineno"> 339</span> <span class="preprocessor"># if(__has_feature(cxx_nonstatic_member_init))</span></div>
+<div class="line"><a name="l00340"></a><span class="lineno"> 340</span> <span class="preprocessor"># define GLM_CXX11_NONSTATIC_MEMBER_INIT</span></div>
+<div class="line"><a name="l00341"></a><span class="lineno"> 341</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00342"></a><span class="lineno"> 342</span> </div>
+<div class="line"><a name="l00343"></a><span class="lineno"> 343</span> <span class="preprocessor"># if(__has_feature(cxx_nullptr))</span></div>
+<div class="line"><a name="l00344"></a><span class="lineno"> 344</span> <span class="preprocessor"># define GLM_CXX11_NULLPTR</span></div>
+<div class="line"><a name="l00345"></a><span class="lineno"> 345</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00346"></a><span class="lineno"> 346</span> </div>
+<div class="line"><a name="l00347"></a><span class="lineno"> 347</span> <span class="preprocessor"># if(__has_feature(cxx_override_control))</span></div>
+<div class="line"><a name="l00348"></a><span class="lineno"> 348</span> <span class="preprocessor"># define GLM_CXX11_OVERRIDE_CONTROL</span></div>
+<div class="line"><a name="l00349"></a><span class="lineno"> 349</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00350"></a><span class="lineno"> 350</span> </div>
+<div class="line"><a name="l00351"></a><span class="lineno"> 351</span> <span class="preprocessor"># if(__has_feature(cxx_reference_qualified_functions))</span></div>
+<div class="line"><a name="l00352"></a><span class="lineno"> 352</span> <span class="preprocessor"># define GLM_CXX11_REFERENCE_QUALIFIED_FUNCTIONS</span></div>
+<div class="line"><a name="l00353"></a><span class="lineno"> 353</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00354"></a><span class="lineno"> 354</span> </div>
+<div class="line"><a name="l00355"></a><span class="lineno"> 355</span> <span class="preprocessor"># if(__has_feature(cxx_range_for))</span></div>
+<div class="line"><a name="l00356"></a><span class="lineno"> 356</span> <span class="preprocessor"># define GLM_CXX11_RANGE_FOR</span></div>
+<div class="line"><a name="l00357"></a><span class="lineno"> 357</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00358"></a><span class="lineno"> 358</span> </div>
+<div class="line"><a name="l00359"></a><span class="lineno"> 359</span> <span class="preprocessor"># if(__has_feature(cxx_raw_string_literals))</span></div>
+<div class="line"><a name="l00360"></a><span class="lineno"> 360</span> <span class="preprocessor"># define GLM_CXX11_RAW_STRING_LITERALS</span></div>
+<div class="line"><a name="l00361"></a><span class="lineno"> 361</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00362"></a><span class="lineno"> 362</span> </div>
+<div class="line"><a name="l00363"></a><span class="lineno"> 363</span> <span class="preprocessor"># if(__has_feature(cxx_rvalue_references))</span></div>
+<div class="line"><a name="l00364"></a><span class="lineno"> 364</span> <span class="preprocessor"># define GLM_CXX11_RVALUE_REFERENCES</span></div>
+<div class="line"><a name="l00365"></a><span class="lineno"> 365</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00366"></a><span class="lineno"> 366</span> </div>
+<div class="line"><a name="l00367"></a><span class="lineno"> 367</span> <span class="preprocessor"># if(__has_feature(cxx_static_assert))</span></div>
+<div class="line"><a name="l00368"></a><span class="lineno"> 368</span> <span class="preprocessor"># define GLM_CXX11_STATIC_ASSERT</span></div>
+<div class="line"><a name="l00369"></a><span class="lineno"> 369</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00370"></a><span class="lineno"> 370</span> </div>
+<div class="line"><a name="l00371"></a><span class="lineno"> 371</span> <span class="preprocessor"># if(__has_feature(cxx_auto_type))</span></div>
+<div class="line"><a name="l00372"></a><span class="lineno"> 372</span> <span class="preprocessor"># define GLM_CXX11_AUTO_TYPE</span></div>
+<div class="line"><a name="l00373"></a><span class="lineno"> 373</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00374"></a><span class="lineno"> 374</span> </div>
+<div class="line"><a name="l00375"></a><span class="lineno"> 375</span> <span class="preprocessor"># if(__has_feature(cxx_strong_enums))</span></div>
+<div class="line"><a name="l00376"></a><span class="lineno"> 376</span> <span class="preprocessor"># define GLM_CXX11_STRONG_ENUMS</span></div>
+<div class="line"><a name="l00377"></a><span class="lineno"> 377</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00378"></a><span class="lineno"> 378</span> </div>
+<div class="line"><a name="l00379"></a><span class="lineno"> 379</span> <span class="preprocessor"># if(__has_feature(cxx_trailing_return))</span></div>
+<div class="line"><a name="l00380"></a><span class="lineno"> 380</span> <span class="preprocessor"># define GLM_CXX11_TRAILING_RETURN</span></div>
+<div class="line"><a name="l00381"></a><span class="lineno"> 381</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00382"></a><span class="lineno"> 382</span> </div>
+<div class="line"><a name="l00383"></a><span class="lineno"> 383</span> <span class="preprocessor"># if(__has_feature(cxx_unicode_literals))</span></div>
+<div class="line"><a name="l00384"></a><span class="lineno"> 384</span> <span class="preprocessor"># define GLM_CXX11_UNICODE_LITERALS</span></div>
+<div class="line"><a name="l00385"></a><span class="lineno"> 385</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00386"></a><span class="lineno"> 386</span> </div>
+<div class="line"><a name="l00387"></a><span class="lineno"> 387</span> <span class="preprocessor"># if(__has_feature(cxx_unrestricted_unions))</span></div>
+<div class="line"><a name="l00388"></a><span class="lineno"> 388</span> <span class="preprocessor"># define GLM_CXX11_UNRESTRICTED_UNIONS</span></div>
+<div class="line"><a name="l00389"></a><span class="lineno"> 389</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00390"></a><span class="lineno"> 390</span> </div>
+<div class="line"><a name="l00391"></a><span class="lineno"> 391</span> <span class="preprocessor"># if(__has_feature(cxx_user_literals))</span></div>
+<div class="line"><a name="l00392"></a><span class="lineno"> 392</span> <span class="preprocessor"># define GLM_CXX11_USER_LITERALS</span></div>
+<div class="line"><a name="l00393"></a><span class="lineno"> 393</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00394"></a><span class="lineno"> 394</span> </div>
+<div class="line"><a name="l00395"></a><span class="lineno"> 395</span> <span class="preprocessor"># if(__has_feature(cxx_variadic_templates))</span></div>
+<div class="line"><a name="l00396"></a><span class="lineno"> 396</span> <span class="preprocessor"># define GLM_CXX11_VARIADIC_TEMPLATES</span></div>
+<div class="line"><a name="l00397"></a><span class="lineno"> 397</span> <span class="preprocessor"># endif</span></div>
+<div class="line"><a name="l00398"></a><span class="lineno"> 398</span> </div>
+<div class="line"><a name="l00399"></a><span class="lineno"> 399</span> <span class="preprocessor">#endif//(GLM_COMPILER & GLM_COMPILER_CLANG)</span></div>
+</div><!-- fragment --></div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated by  <a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.10
+</small></address>
+</body>
+</html>
diff --git a/src/third_party/glm/doc/api/a00002.html b/src/third_party/glm/doc/api/a00002.html
new file mode 100644
index 0000000..523bac0
--- /dev/null
+++ b/src/third_party/glm/doc/api/a00002.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.10"/>
+<title>0.9.8: _fixes.hpp File Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="logo.png"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">0.9.8
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.10 -->
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div id="navrow2" class="tabs2">
+ <ul class="tablist">
+ <li><a href="files.html"><span>File List</span></a></li>
+ </ul>
+ </div>
+<div id="nav-path" class="navpath">
+ <ul>
+<li class="navelem"><a class="el" href="dir_275089585c7fc1b5fd5d7d42c69cb1da.html">D:</a></li><li class="navelem"><a class="el" href="dir_7b98f88bffbed4b390b5f8f520d9c08e.html">Source</a></li><li class="navelem"><a class="el" href="dir_1f76e953200861345293ade84ac7fb6c.html">G-Truc</a></li><li class="navelem"><a class="el" href="dir_e29b03b892e0e25920d021a614d4db9b.html">glm</a></li><li class="navelem"><a class="el" href="dir_5ce58d942b2d0776e17a9a58abc01e04.html">glm</a></li><li class="navelem"><a class="el" href="dir_e529a619cfdec1fa4c331fb042fd332f.html">detail</a></li> </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+ <div class="headertitle">
+<div class="title">_fixes.hpp File Reference</div> </div>
+</div><!--header-->
+<div class="contents">
+
+<p><a href="a00002_source.html">Go to the source code of this file.</a></p>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p><a class="el" href="a00156.html">GLM Core</a> </p>
+
+<p>Definition in file <a class="el" href="a00002_source.html">_fixes.hpp</a>.</p>
+</div></div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated by  <a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.10
+</small></address>
+</body>
+</html>
diff --git a/src/third_party/glm/doc/api/a00002_source.html b/src/third_party/glm/doc/api/a00002_source.html
new file mode 100644
index 0000000..0941ab7
--- /dev/null
+++ b/src/third_party/glm/doc/api/a00002_source.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.10"/>
+<title>0.9.8: _fixes.hpp Source File</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="logo.png"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">0.9.8
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.10 -->
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div id="navrow2" class="tabs2">
+ <ul class="tablist">
+ <li><a href="files.html"><span>File List</span></a></li>
+ </ul>
+ </div>
+<div id="nav-path" class="navpath">
+ <ul>
+<li class="navelem"><a class="el" href="dir_275089585c7fc1b5fd5d7d42c69cb1da.html">D:</a></li><li class="navelem"><a class="el" href="dir_7b98f88bffbed4b390b5f8f520d9c08e.html">Source</a></li><li class="navelem"><a class="el" href="dir_1f76e953200861345293ade84ac7fb6c.html">G-Truc</a></li><li class="navelem"><a class="el" href="dir_e29b03b892e0e25920d021a614d4db9b.html">glm</a></li><li class="navelem"><a class="el" href="dir_5ce58d942b2d0776e17a9a58abc01e04.html">glm</a></li><li class="navelem"><a class="el" href="dir_e529a619cfdec1fa4c331fb042fd332f.html">detail</a></li> </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+ <div class="headertitle">
+<div class="title">_fixes.hpp</div> </div>
+</div><!--header-->
+<div class="contents">
+<a href="a00002.html">Go to the documentation of this file.</a><div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> </div>
+<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> <span class="preprocessor">#include <cmath></span></div>
+<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> </div>
+<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> <span class="preprocessor">#ifdef max</span></div>
+<div class="line"><a name="l00008"></a><span class="lineno"> 8</span> <span class="preprocessor">#undef max</span></div>
+<div class="line"><a name="l00009"></a><span class="lineno"> 9</span> <span class="preprocessor">#endif</span></div>
+<div class="line"><a name="l00010"></a><span class="lineno"> 10</span> </div>
+<div class="line"><a name="l00012"></a><span class="lineno"> 12</span> <span class="preprocessor">#ifdef min</span></div>
+<div class="line"><a name="l00013"></a><span class="lineno"> 13</span> <span class="preprocessor">#undef min</span></div>
+<div class="line"><a name="l00014"></a><span class="lineno"> 14</span> <span class="preprocessor">#endif</span></div>
+<div class="line"><a name="l00015"></a><span class="lineno"> 15</span> </div>
+<div class="line"><a name="l00017"></a><span class="lineno"> 17</span> <span class="preprocessor">#ifdef isnan</span></div>
+<div class="line"><a name="l00018"></a><span class="lineno"> 18</span> <span class="preprocessor">#undef isnan</span></div>
+<div class="line"><a name="l00019"></a><span class="lineno"> 19</span> <span class="preprocessor">#endif</span></div>
+<div class="line"><a name="l00020"></a><span class="lineno"> 20</span> </div>
+<div class="line"><a name="l00022"></a><span class="lineno"> 22</span> <span class="preprocessor">#ifdef isinf</span></div>
+<div class="line"><a name="l00023"></a><span class="lineno"> 23</span> <span class="preprocessor">#undef isinf</span></div>
+<div class="line"><a name="l00024"></a><span class="lineno"> 24</span> <span class="preprocessor">#endif</span></div>
+<div class="line"><a name="l00025"></a><span class="lineno"> 25</span> </div>
+<div class="line"><a name="l00027"></a><span class="lineno"> 27</span> <span class="preprocessor">#ifdef log2</span></div>
+<div class="line"><a name="l00028"></a><span class="lineno"> 28</span> <span class="preprocessor">#undef log2</span></div>
+<div class="line"><a name="l00029"></a><span class="lineno"> 29</span> <span class="preprocessor">#endif</span></div>
+<div class="line"><a name="l00030"></a><span class="lineno"> 30</span> </div>
+</div><!-- fragment --></div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated by  <a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.10
+</small></address>
+</body>
+</html>
diff --git a/src/third_party/glm/doc/api/a00003.html b/src/third_party/glm/doc/api/a00003.html
new file mode 100644
index 0000000..b5ad770
--- /dev/null
+++ b/src/third_party/glm/doc/api/a00003.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.10"/>
+<title>0.9.8: _noise.hpp File Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="logo.png"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">0.9.8
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.10 -->
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div id="navrow2" class="tabs2">
+ <ul class="tablist">
+ <li><a href="files.html"><span>File List</span></a></li>
+ </ul>
+ </div>
+<div id="nav-path" class="navpath">
+ <ul>
+<li class="navelem"><a class="el" href="dir_275089585c7fc1b5fd5d7d42c69cb1da.html">D:</a></li><li class="navelem"><a class="el" href="dir_7b98f88bffbed4b390b5f8f520d9c08e.html">Source</a></li><li class="navelem"><a class="el" href="dir_1f76e953200861345293ade84ac7fb6c.html">G-Truc</a></li><li class="navelem"><a class="el" href="dir_e29b03b892e0e25920d021a614d4db9b.html">glm</a></li><li class="navelem"><a class="el" href="dir_5ce58d942b2d0776e17a9a58abc01e04.html">glm</a></li><li class="navelem"><a class="el" href="dir_e529a619cfdec1fa4c331fb042fd332f.html">detail</a></li> </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+ <div class="headertitle">
+<div class="title">_noise.hpp File Reference</div> </div>
+</div><!--header-->
+<div class="contents">
+
+<p><a href="a00003_source.html">Go to the source code of this file.</a></p>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p><a class="el" href="a00156.html">GLM Core</a> </p>
+
+<p>Definition in file <a class="el" href="a00003_source.html">_noise.hpp</a>.</p>
+</div></div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated by  <a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.10
+</small></address>
+</body>
+</html>
diff --git a/src/third_party/glm/doc/api/a00003_source.html b/src/third_party/glm/doc/api/a00003_source.html
new file mode 100644
index 0000000..2575ec4
--- /dev/null
+++ b/src/third_party/glm/doc/api/a00003_source.html
@@ -0,0 +1,167 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.10"/>
+<title>0.9.8: _noise.hpp Source File</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="logo.png"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">0.9.8
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.10 -->
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div id="navrow2" class="tabs2">
+ <ul class="tablist">
+ <li><a href="files.html"><span>File List</span></a></li>
+ </ul>
+ </div>
+<div id="nav-path" class="navpath">
+ <ul>
+<li class="navelem"><a class="el" href="dir_275089585c7fc1b5fd5d7d42c69cb1da.html">D:</a></li><li class="navelem"><a class="el" href="dir_7b98f88bffbed4b390b5f8f520d9c08e.html">Source</a></li><li class="navelem"><a class="el" href="dir_1f76e953200861345293ade84ac7fb6c.html">G-Truc</a></li><li class="navelem"><a class="el" href="dir_e29b03b892e0e25920d021a614d4db9b.html">glm</a></li><li class="navelem"><a class="el" href="dir_5ce58d942b2d0776e17a9a58abc01e04.html">glm</a></li><li class="navelem"><a class="el" href="dir_e529a619cfdec1fa4c331fb042fd332f.html">detail</a></li> </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+ <div class="headertitle">
+<div class="title">_noise.hpp</div> </div>
+</div><!--header-->
+<div class="contents">
+<a href="a00003.html">Go to the documentation of this file.</a><div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> </div>
+<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> <span class="preprocessor">#pragma once</span></div>
+<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> </div>
+<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> <span class="preprocessor">#include "../vec2.hpp"</span></div>
+<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> <span class="preprocessor">#include "../vec3.hpp"</span></div>
+<div class="line"><a name="l00008"></a><span class="lineno"> 8</span> <span class="preprocessor">#include "../vec4.hpp"</span></div>
+<div class="line"><a name="l00009"></a><span class="lineno"> 9</span> <span class="preprocessor">#include "../common.hpp"</span></div>
+<div class="line"><a name="l00010"></a><span class="lineno"> 10</span> </div>
+<div class="line"><a name="l00011"></a><span class="lineno"> 11</span> <span class="keyword">namespace </span><a class="code" href="a00141.html">glm</a>{</div>
+<div class="line"><a name="l00012"></a><span class="lineno"> 12</span> <span class="keyword">namespace </span>detail</div>
+<div class="line"><a name="l00013"></a><span class="lineno"> 13</span> {</div>
+<div class="line"><a name="l00014"></a><span class="lineno"> 14</span>  <span class="keyword">template</span> <<span class="keyword">typename</span> T></div>
+<div class="line"><a name="l00015"></a><span class="lineno"> 15</span>  GLM_FUNC_QUALIFIER T mod289(T <span class="keyword">const</span> & x)</div>
+<div class="line"><a name="l00016"></a><span class="lineno"> 16</span>  {</div>
+<div class="line"><a name="l00017"></a><span class="lineno"> 17</span>  <span class="keywordflow">return</span> x - <a class="code" href="a00146.html#ga568b822b78f045f77c3325e165b44d5d">floor</a>(x * static_cast<T>(1.0) / static_cast<T>(289.0)) * <span class="keyword">static_cast<</span>T<span class="keyword">></span>(289.0);</div>
+<div class="line"><a name="l00018"></a><span class="lineno"> 18</span>  }</div>
+<div class="line"><a name="l00019"></a><span class="lineno"> 19</span> </div>
+<div class="line"><a name="l00020"></a><span class="lineno"> 20</span>  <span class="keyword">template</span> <<span class="keyword">typename</span> T></div>
+<div class="line"><a name="l00021"></a><span class="lineno"> 21</span>  GLM_FUNC_QUALIFIER T permute(T <span class="keyword">const</span> & x)</div>
+<div class="line"><a name="l00022"></a><span class="lineno"> 22</span>  {</div>
+<div class="line"><a name="l00023"></a><span class="lineno"> 23</span>  <span class="keywordflow">return</span> mod289(((x * static_cast<T>(34)) + static_cast<T>(1)) * x);</div>
+<div class="line"><a name="l00024"></a><span class="lineno"> 24</span>  }</div>
+<div class="line"><a name="l00025"></a><span class="lineno"> 25</span> </div>
+<div class="line"><a name="l00026"></a><span class="lineno"> 26</span>  <span class="keyword">template</span> <<span class="keyword">typename</span> T, precision P></div>
+<div class="line"><a name="l00027"></a><span class="lineno"> 27</span>  GLM_FUNC_QUALIFIER tvec2<T, P> permute(tvec2<T, P> <span class="keyword">const</span> & x)</div>
+<div class="line"><a name="l00028"></a><span class="lineno"> 28</span>  {</div>
+<div class="line"><a name="l00029"></a><span class="lineno"> 29</span>  <span class="keywordflow">return</span> mod289(((x * static_cast<T>(34)) + static_cast<T>(1)) * x);</div>
+<div class="line"><a name="l00030"></a><span class="lineno"> 30</span>  }</div>
+<div class="line"><a name="l00031"></a><span class="lineno"> 31</span>  </div>
+<div class="line"><a name="l00032"></a><span class="lineno"> 32</span>  <span class="keyword">template</span> <<span class="keyword">typename</span> T, precision P></div>
+<div class="line"><a name="l00033"></a><span class="lineno"> 33</span>  GLM_FUNC_QUALIFIER tvec3<T, P> permute(tvec3<T, P> <span class="keyword">const</span> & x)</div>
+<div class="line"><a name="l00034"></a><span class="lineno"> 34</span>  {</div>
+<div class="line"><a name="l00035"></a><span class="lineno"> 35</span>  <span class="keywordflow">return</span> mod289(((x * static_cast<T>(34)) + static_cast<T>(1)) * x);</div>
+<div class="line"><a name="l00036"></a><span class="lineno"> 36</span>  }</div>
+<div class="line"><a name="l00037"></a><span class="lineno"> 37</span>  </div>
+<div class="line"><a name="l00038"></a><span class="lineno"> 38</span>  <span class="keyword">template</span> <<span class="keyword">typename</span> T, precision P></div>
+<div class="line"><a name="l00039"></a><span class="lineno"> 39</span>  GLM_FUNC_QUALIFIER tvec4<T, P> permute(tvec4<T, P> <span class="keyword">const</span> & x)</div>
+<div class="line"><a name="l00040"></a><span class="lineno"> 40</span>  {</div>
+<div class="line"><a name="l00041"></a><span class="lineno"> 41</span>  <span class="keywordflow">return</span> mod289(((x * static_cast<T>(34)) + static_cast<T>(1)) * x);</div>
+<div class="line"><a name="l00042"></a><span class="lineno"> 42</span>  }</div>
+<div class="line"><a name="l00043"></a><span class="lineno"> 43</span> <span class="comment">/*</span></div>
+<div class="line"><a name="l00044"></a><span class="lineno"> 44</span> <span class="comment"> template <typename T, precision P, template<typename> class vecType></span></div>
+<div class="line"><a name="l00045"></a><span class="lineno"> 45</span> <span class="comment"> GLM_FUNC_QUALIFIER vecType<T, P> permute(vecType<T, P> const & x)</span></div>
+<div class="line"><a name="l00046"></a><span class="lineno"> 46</span> <span class="comment"> {</span></div>
+<div class="line"><a name="l00047"></a><span class="lineno"> 47</span> <span class="comment"> return mod289(((x * T(34)) + T(1)) * x);</span></div>
+<div class="line"><a name="l00048"></a><span class="lineno"> 48</span> <span class="comment"> }</span></div>
+<div class="line"><a name="l00049"></a><span class="lineno"> 49</span> <span class="comment">*/</span></div>
+<div class="line"><a name="l00050"></a><span class="lineno"> 50</span>  <span class="keyword">template</span> <<span class="keyword">typename</span> T></div>
+<div class="line"><a name="l00051"></a><span class="lineno"> 51</span>  GLM_FUNC_QUALIFIER T taylorInvSqrt(T <span class="keyword">const</span> & r)</div>
+<div class="line"><a name="l00052"></a><span class="lineno"> 52</span>  {</div>
+<div class="line"><a name="l00053"></a><span class="lineno"> 53</span>  <span class="keywordflow">return</span> T(1.79284291400159) - T(0.85373472095314) * r;</div>
+<div class="line"><a name="l00054"></a><span class="lineno"> 54</span>  }</div>
+<div class="line"><a name="l00055"></a><span class="lineno"> 55</span>  </div>
+<div class="line"><a name="l00056"></a><span class="lineno"> 56</span>  <span class="keyword">template</span> <<span class="keyword">typename</span> T, precision P></div>
+<div class="line"><a name="l00057"></a><span class="lineno"> 57</span>  GLM_FUNC_QUALIFIER tvec2<T, P> taylorInvSqrt(tvec2<T, P> <span class="keyword">const</span> & r)</div>
+<div class="line"><a name="l00058"></a><span class="lineno"> 58</span>  {</div>
+<div class="line"><a name="l00059"></a><span class="lineno"> 59</span>  <span class="keywordflow">return</span> T(1.79284291400159) - T(0.85373472095314) * r;</div>
+<div class="line"><a name="l00060"></a><span class="lineno"> 60</span>  }</div>
+<div class="line"><a name="l00061"></a><span class="lineno"> 61</span>  </div>
+<div class="line"><a name="l00062"></a><span class="lineno"> 62</span>  <span class="keyword">template</span> <<span class="keyword">typename</span> T, precision P></div>
+<div class="line"><a name="l00063"></a><span class="lineno"> 63</span>  GLM_FUNC_QUALIFIER tvec3<T, P> taylorInvSqrt(tvec3<T, P> <span class="keyword">const</span> & r)</div>
+<div class="line"><a name="l00064"></a><span class="lineno"> 64</span>  {</div>
+<div class="line"><a name="l00065"></a><span class="lineno"> 65</span>  <span class="keywordflow">return</span> T(1.79284291400159) - T(0.85373472095314) * r;</div>
+<div class="line"><a name="l00066"></a><span class="lineno"> 66</span>  }</div>
+<div class="line"><a name="l00067"></a><span class="lineno"> 67</span>  </div>
+<div class="line"><a name="l00068"></a><span class="lineno"> 68</span>  <span class="keyword">template</span> <<span class="keyword">typename</span> T, precision P></div>
+<div class="line"><a name="l00069"></a><span class="lineno"> 69</span>  GLM_FUNC_QUALIFIER tvec4<T, P> taylorInvSqrt(tvec4<T, P> <span class="keyword">const</span> & r)</div>
+<div class="line"><a name="l00070"></a><span class="lineno"> 70</span>  {</div>
+<div class="line"><a name="l00071"></a><span class="lineno"> 71</span>  <span class="keywordflow">return</span> T(1.79284291400159) - T(0.85373472095314) * r;</div>
+<div class="line"><a name="l00072"></a><span class="lineno"> 72</span>  }</div>
+<div class="line"><a name="l00073"></a><span class="lineno"> 73</span> <span class="comment">/*</span></div>
+<div class="line"><a name="l00074"></a><span class="lineno"> 74</span> <span class="comment"> template <typename T, precision P, template<typename> class vecType></span></div>
+<div class="line"><a name="l00075"></a><span class="lineno"> 75</span> <span class="comment"> GLM_FUNC_QUALIFIER vecType<T, P> taylorInvSqrt(vecType<T, P> const & r)</span></div>
+<div class="line"><a name="l00076"></a><span class="lineno"> 76</span> <span class="comment"> {</span></div>
+<div class="line"><a name="l00077"></a><span class="lineno"> 77</span> <span class="comment"> return T(1.79284291400159) - T(0.85373472095314) * r;</span></div>
+<div class="line"><a name="l00078"></a><span class="lineno"> 78</span> <span class="comment"> }</span></div>
+<div class="line"><a name="l00079"></a><span class="lineno"> 79</span> <span class="comment">*/</span></div>
+<div class="line"><a name="l00080"></a><span class="lineno"> 80</span>  </div>
+<div class="line"><a name="l00081"></a><span class="lineno"> 81</span>  <span class="keyword">template</span> <<span class="keyword">typename</span> T, precision P></div>
+<div class="line"><a name="l00082"></a><span class="lineno"> 82</span>  GLM_FUNC_QUALIFIER tvec2<T, P> fade(tvec2<T, P> <span class="keyword">const</span> & t)</div>
+<div class="line"><a name="l00083"></a><span class="lineno"> 83</span>  {</div>
+<div class="line"><a name="l00084"></a><span class="lineno"> 84</span>  <span class="keywordflow">return</span> (t * t * t) * (t * (t * T(6) - T(15)) + T(10));</div>
+<div class="line"><a name="l00085"></a><span class="lineno"> 85</span>  }</div>
+<div class="line"><a name="l00086"></a><span class="lineno"> 86</span>  </div>
+<div class="line"><a name="l00087"></a><span class="lineno"> 87</span>  <span class="keyword">template</span> <<span class="keyword">typename</span> T, precision P></div>
+<div class="line"><a name="l00088"></a><span class="lineno"> 88</span>  GLM_FUNC_QUALIFIER tvec3<T, P> fade(tvec3<T, P> <span class="keyword">const</span> & t)</div>
+<div class="line"><a name="l00089"></a><span class="lineno"> 89</span>  {</div>
+<div class="line"><a name="l00090"></a><span class="lineno"> 90</span>  <span class="keywordflow">return</span> (t * t * t) * (t * (t * T(6) - T(15)) + T(10));</div>
+<div class="line"><a name="l00091"></a><span class="lineno"> 91</span>  }</div>
+<div class="line"><a name="l00092"></a><span class="lineno"> 92</span>  </div>
+<div class="line"><a name="l00093"></a><span class="lineno"> 93</span>  <span class="keyword">template</span> <<span class="keyword">typename</span> T, precision P></div>
+<div class="line"><a name="l00094"></a><span class="lineno"> 94</span>  GLM_FUNC_QUALIFIER tvec4<T, P> fade(tvec4<T, P> <span class="keyword">const</span> & t)</div>
+<div class="line"><a name="l00095"></a><span class="lineno"> 95</span>  {</div>
+<div class="line"><a name="l00096"></a><span class="lineno"> 96</span>  <span class="keywordflow">return</span> (t * t * t) * (t * (t * T(6) - T(15)) + T(10));</div>
+<div class="line"><a name="l00097"></a><span class="lineno"> 97</span>  }</div>
+<div class="line"><a name="l00098"></a><span class="lineno"> 98</span> <span class="comment">/*</span></div>
+<div class="line"><a name="l00099"></a><span class="lineno"> 99</span> <span class="comment"> template <typename T, precision P, template <typename> class vecType></span></div>
+<div class="line"><a name="l00100"></a><span class="lineno"> 100</span> <span class="comment"> GLM_FUNC_QUALIFIER vecType<T, P> fade(vecType<T, P> const & t)</span></div>
+<div class="line"><a name="l00101"></a><span class="lineno"> 101</span> <span class="comment"> {</span></div>
+<div class="line"><a name="l00102"></a><span class="lineno"> 102</span> <span class="comment"> return (t * t * t) * (t * (t * T(6) - T(15)) + T(10));</span></div>
+<div class="line"><a name="l00103"></a><span class="lineno"> 103</span> <span class="comment"> }</span></div>
+<div class="line"><a name="l00104"></a><span class="lineno"> 104</span> <span class="comment">*/</span></div>
+<div class="line"><a name="l00105"></a><span class="lineno"> 105</span> }<span class="comment">//namespace detail</span></div>
+<div class="line"><a name="l00106"></a><span class="lineno"> 106</span> }<span class="comment">//namespace glm</span></div>
+<div class="line"><a name="l00107"></a><span class="lineno"> 107</span> </div>
+<div class="ttc" id="a00141_html"><div class="ttname"><a href="a00141.html">glm</a></div><div class="ttdef"><b>Definition:</b> <a href="a00003_source.html#l00011">_noise.hpp:11</a></div></div>
+<div class="ttc" id="a00146_html_ga568b822b78f045f77c3325e165b44d5d"><div class="ttname"><a href="a00146.html#ga568b822b78f045f77c3325e165b44d5d">glm::floor</a></div><div class="ttdeci">GLM_FUNC_DECL vecType< T, P > floor(vecType< T, P > const &x)</div><div class="ttdoc">Returns a value equal to the nearest integer that is less then or equal to x. </div></div>
+</div><!-- fragment --></div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated by  <a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.10
+</small></address>
+</body>
+</html>
diff --git a/src/third_party/glm/doc/api/a00004.html b/src/third_party/glm/doc/api/a00004.html
new file mode 100644
index 0000000..dc12366
--- /dev/null
+++ b/src/third_party/glm/doc/api/a00004.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.10"/>
+<title>0.9.8: _swizzle.hpp File Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="logo.png"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">0.9.8
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.10 -->
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div id="navrow2" class="tabs2">
+ <ul class="tablist">
+ <li><a href="files.html"><span>File List</span></a></li>
+ </ul>
+ </div>
+<div id="nav-path" class="navpath">
+ <ul>
+<li class="navelem"><a class="el" href="dir_275089585c7fc1b5fd5d7d42c69cb1da.html">D:</a></li><li class="navelem"><a class="el" href="dir_7b98f88bffbed4b390b5f8f520d9c08e.html">Source</a></li><li class="navelem"><a class="el" href="dir_1f76e953200861345293ade84ac7fb6c.html">G-Truc</a></li><li class="navelem"><a class="el" href="dir_e29b03b892e0e25920d021a614d4db9b.html">glm</a></li><li class="navelem"><a class="el" href="dir_5ce58d942b2d0776e17a9a58abc01e04.html">glm</a></li><li class="navelem"><a class="el" href="dir_e529a619cfdec1fa4c331fb042fd332f.html">detail</a></li> </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+ <div class="headertitle">
+<div class="title">_swizzle.hpp File Reference</div> </div>
+</div><!--header-->
+<div class="contents">
+
+<p><a href="a00004_source.html">Go to the source code of this file.</a></p>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p><a class="el" href="a00156.html">GLM Core</a> </p>
+
+<p>Definition in file <a class="el" href="a00004_source.html">_swizzle.hpp</a>.</p>
+</div></div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated by  <a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.10
+</small></address>
+</body>
+</html>
diff --git a/src/third_party/glm/doc/api/a00004_source.html b/src/third_party/glm/doc/api/a00004_source.html
new file mode 100644
index 0000000..2402657
--- /dev/null
+++ b/src/third_party/glm/doc/api/a00004_source.html
@@ -0,0 +1,857 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.10"/>
+<title>0.9.8: _swizzle.hpp Source File</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="logo.png"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">0.9.8
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.10 -->
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div id="navrow2" class="tabs2">
+ <ul class="tablist">
+ <li><a href="files.html"><span>File List</span></a></li>
+ </ul>
+ </div>
+<div id="nav-path" class="navpath">
+ <ul>
+<li class="navelem"><a class="el" href="dir_275089585c7fc1b5fd5d7d42c69cb1da.html">D:</a></li><li class="navelem"><a class="el" href="dir_7b98f88bffbed4b390b5f8f520d9c08e.html">Source</a></li><li class="navelem"><a class="el" href="dir_1f76e953200861345293ade84ac7fb6c.html">G-Truc</a></li><li class="navelem"><a class="el" href="dir_e29b03b892e0e25920d021a614d4db9b.html">glm</a></li><li class="navelem"><a class="el" href="dir_5ce58d942b2d0776e17a9a58abc01e04.html">glm</a></li><li class="navelem"><a class="el" href="dir_e529a619cfdec1fa4c331fb042fd332f.html">detail</a></li> </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+ <div class="headertitle">
+<div class="title">_swizzle.hpp</div> </div>
+</div><!--header-->
+<div class="contents">
+<a href="a00004.html">Go to the documentation of this file.</a><div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> </div>
+<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> <span class="preprocessor">#pragma once</span></div>
+<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> </div>
+<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> <span class="keyword">namespace </span><a class="code" href="a00141.html">glm</a>{</div>
+<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> <span class="keyword">namespace </span>detail</div>
+<div class="line"><a name="l00008"></a><span class="lineno"> 8</span> {</div>
+<div class="line"><a name="l00009"></a><span class="lineno"> 9</span>  <span class="comment">// Internal class for implementing swizzle operators</span></div>
+<div class="line"><a name="l00010"></a><span class="lineno"> 10</span>  <span class="keyword">template</span> <<span class="keyword">typename</span> T, <span class="keywordtype">int</span> N></div>
+<div class="line"><a name="l00011"></a><span class="lineno"> 11</span>  <span class="keyword">struct </span>_swizzle_base0</div>
+<div class="line"><a name="l00012"></a><span class="lineno"> 12</span>  {</div>
+<div class="line"><a name="l00013"></a><span class="lineno"> 13</span>  <span class="keyword">protected</span>:</div>
+<div class="line"><a name="l00014"></a><span class="lineno"> 14</span>  GLM_FUNC_QUALIFIER T& elem(<span class="keywordtype">size_t</span> i){ <span class="keywordflow">return</span> (reinterpret_cast<T*>(_buffer))[i]; }</div>
+<div class="line"><a name="l00015"></a><span class="lineno"> 15</span>  GLM_FUNC_QUALIFIER T <span class="keyword">const</span>& elem(<span class="keywordtype">size_t</span> i)<span class="keyword"> const</span>{ <span class="keywordflow">return</span> (reinterpret_cast<const T*>(_buffer))[i]; }</div>
+<div class="line"><a name="l00016"></a><span class="lineno"> 16</span> </div>
+<div class="line"><a name="l00017"></a><span class="lineno"> 17</span>  <span class="comment">// Use an opaque buffer to *ensure* the compiler doesn't call a constructor.</span></div>
+<div class="line"><a name="l00018"></a><span class="lineno"> 18</span>  <span class="comment">// The size 1 buffer is assumed to aligned to the actual members so that the</span></div>
+<div class="line"><a name="l00019"></a><span class="lineno"> 19</span>  <span class="comment">// elem() </span></div>
+<div class="line"><a name="l00020"></a><span class="lineno"> 20</span>  <span class="keywordtype">char</span> _buffer[1];</div>
+<div class="line"><a name="l00021"></a><span class="lineno"> 21</span>  };</div>
+<div class="line"><a name="l00022"></a><span class="lineno"> 22</span> </div>
+<div class="line"><a name="l00023"></a><span class="lineno"> 23</span>  <span class="keyword">template</span> <<span class="keywordtype">int</span> N, <span class="keyword">typename</span> T, precision P, <span class="keyword">template</span> <<span class="keyword">typename</span>, precision> <span class="keyword">class </span>vecType, <span class="keywordtype">int</span> E0, <span class="keywordtype">int</span> E1, <span class="keywordtype">int</span> E2, <span class="keywordtype">int</span> E3, <span class="keywordtype">bool</span> Aligned></div>
+<div class="line"><a name="l00024"></a><span class="lineno"> 24</span>  <span class="keyword">struct </span>_swizzle_base1 : <span class="keyword">public</span> _swizzle_base0<T, N></div>
+<div class="line"><a name="l00025"></a><span class="lineno"> 25</span>  {</div>
+<div class="line"><a name="l00026"></a><span class="lineno"> 26</span>  };</div>
+<div class="line"><a name="l00027"></a><span class="lineno"> 27</span> </div>
+<div class="line"><a name="l00028"></a><span class="lineno"> 28</span>  <span class="keyword">template</span> <<span class="keyword">typename</span> T, precision P, <span class="keyword">template</span> <<span class="keyword">typename</span>, precision> <span class="keyword">class </span>vecType, <span class="keywordtype">int</span> E0, <span class="keywordtype">int</span> E1, <span class="keywordtype">bool</span> Aligned></div>
+<div class="line"><a name="l00029"></a><span class="lineno"> 29</span>  <span class="keyword">struct </span>_swizzle_base1<2, T, P, vecType, E0,E1,-1,-2, Aligned> : <span class="keyword">public</span> _swizzle_base0<T, 2></div>
+<div class="line"><a name="l00030"></a><span class="lineno"> 30</span>  {</div>
+<div class="line"><a name="l00031"></a><span class="lineno"> 31</span>  GLM_FUNC_QUALIFIER vecType<T, P> operator ()()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> vecType<T, P>(this->elem(E0), this->elem(E1)); }</div>
+<div class="line"><a name="l00032"></a><span class="lineno"> 32</span>  };</div>
+<div class="line"><a name="l00033"></a><span class="lineno"> 33</span> </div>
+<div class="line"><a name="l00034"></a><span class="lineno"> 34</span>  <span class="keyword">template</span> <<span class="keyword">typename</span> T, precision P, <span class="keyword">template</span> <<span class="keyword">typename</span>, precision> <span class="keyword">class </span>vecType, <span class="keywordtype">int</span> E0, <span class="keywordtype">int</span> E1, <span class="keywordtype">int</span> E2, <span class="keywordtype">bool</span> Aligned></div>
+<div class="line"><a name="l00035"></a><span class="lineno"> 35</span>  <span class="keyword">struct </span>_swizzle_base1<3, T, P, vecType, E0,E1,E2,-1, Aligned> : <span class="keyword">public</span> _swizzle_base0<T, 3></div>
+<div class="line"><a name="l00036"></a><span class="lineno"> 36</span>  {</div>
+<div class="line"><a name="l00037"></a><span class="lineno"> 37</span>  GLM_FUNC_QUALIFIER vecType<T, P> operator ()()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> vecType<T, P>(this->elem(E0), this->elem(E1), this->elem(E2)); }</div>
+<div class="line"><a name="l00038"></a><span class="lineno"> 38</span>  };</div>
+<div class="line"><a name="l00039"></a><span class="lineno"> 39</span> </div>
+<div class="line"><a name="l00040"></a><span class="lineno"> 40</span>  <span class="keyword">template</span> <<span class="keyword">typename</span> T, precision P, <span class="keyword">template</span> <<span class="keyword">typename</span>, precision> <span class="keyword">class </span>vecType, <span class="keywordtype">int</span> E0, <span class="keywordtype">int</span> E1, <span class="keywordtype">int</span> E2, <span class="keywordtype">int</span> E3, <span class="keywordtype">bool</span> Aligned></div>
+<div class="line"><a name="l00041"></a><span class="lineno"> 41</span>  <span class="keyword">struct </span>_swizzle_base1<4, T, P, vecType, E0,E1,E2,E3, Aligned> : <span class="keyword">public</span> _swizzle_base0<T, 4></div>
+<div class="line"><a name="l00042"></a><span class="lineno"> 42</span>  { </div>
+<div class="line"><a name="l00043"></a><span class="lineno"> 43</span>  GLM_FUNC_QUALIFIER vecType<T, P> operator ()()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> vecType<T, P>(this->elem(E0), this->elem(E1), this->elem(E2), this->elem(E3)); }</div>
+<div class="line"><a name="l00044"></a><span class="lineno"> 44</span>  };</div>
+<div class="line"><a name="l00045"></a><span class="lineno"> 45</span> </div>
+<div class="line"><a name="l00046"></a><span class="lineno"> 46</span>  <span class="comment">// Internal class for implementing swizzle operators</span></div>
+<div class="line"><a name="l00047"></a><span class="lineno"> 47</span>  <span class="comment">/*</span></div>
+<div class="line"><a name="l00048"></a><span class="lineno"> 48</span> <span class="comment"> Template parameters:</span></div>
+<div class="line"><a name="l00049"></a><span class="lineno"> 49</span> <span class="comment"></span></div>
+<div class="line"><a name="l00050"></a><span class="lineno"> 50</span> <span class="comment"> ValueType = type of scalar values (e.g. float, double)</span></div>
+<div class="line"><a name="l00051"></a><span class="lineno"> 51</span> <span class="comment"> VecType = class the swizzle is applies to (e.g. tvec3<float>)</span></div>
+<div class="line"><a name="l00052"></a><span class="lineno"> 52</span> <span class="comment"> N = number of components in the vector (e.g. 3)</span></div>
+<div class="line"><a name="l00053"></a><span class="lineno"> 53</span> <span class="comment"> E0...3 = what index the n-th element of this swizzle refers to in the unswizzled vec</span></div>
+<div class="line"><a name="l00054"></a><span class="lineno"> 54</span> <span class="comment"></span></div>
+<div class="line"><a name="l00055"></a><span class="lineno"> 55</span> <span class="comment"> DUPLICATE_ELEMENTS = 1 if there is a repeated element, 0 otherwise (used to specialize swizzles</span></div>
+<div class="line"><a name="l00056"></a><span class="lineno"> 56</span> <span class="comment"> containing duplicate elements so that they cannot be used as r-values). </span></div>
+<div class="line"><a name="l00057"></a><span class="lineno"> 57</span> <span class="comment"> */</span></div>
+<div class="line"><a name="l00058"></a><span class="lineno"> 58</span>  <span class="keyword">template</span> <<span class="keywordtype">int</span> N, <span class="keyword">typename</span> T, precision P, <span class="keyword">template</span> <<span class="keyword">typename</span>, precision> <span class="keyword">class </span>vecType, <span class="keywordtype">int</span> E0, <span class="keywordtype">int</span> E1, <span class="keywordtype">int</span> E2, <span class="keywordtype">int</span> E3, <span class="keywordtype">int</span> DUPLICATE_ELEMENTS></div>
+<div class="line"><a name="l00059"></a><span class="lineno"> 59</span>  <span class="keyword">struct </span>_swizzle_base2 : <span class="keyword">public</span> _swizzle_base1<N, T, P, vecType, E0,E1,E2,E3, detail::is_aligned<P>::value></div>
+<div class="line"><a name="l00060"></a><span class="lineno"> 60</span>  {</div>
+<div class="line"><a name="l00061"></a><span class="lineno"> 61</span>  GLM_FUNC_QUALIFIER _swizzle_base2& operator= (<span class="keyword">const</span> T& t)</div>
+<div class="line"><a name="l00062"></a><span class="lineno"> 62</span>  {</div>
+<div class="line"><a name="l00063"></a><span class="lineno"> 63</span>  <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < N; ++i)</div>
+<div class="line"><a name="l00064"></a><span class="lineno"> 64</span>  (*<span class="keyword">this</span>)[i] = t;</div>
+<div class="line"><a name="l00065"></a><span class="lineno"> 65</span>  <span class="keywordflow">return</span> *<span class="keyword">this</span>;</div>
+<div class="line"><a name="l00066"></a><span class="lineno"> 66</span>  }</div>
+<div class="line"><a name="l00067"></a><span class="lineno"> 67</span> </div>
+<div class="line"><a name="l00068"></a><span class="lineno"> 68</span>  GLM_FUNC_QUALIFIER _swizzle_base2& operator= (vecType<T, P> <span class="keyword">const</span>& that)</div>
+<div class="line"><a name="l00069"></a><span class="lineno"> 69</span>  {</div>
+<div class="line"><a name="l00070"></a><span class="lineno"> 70</span>  <span class="keyword">struct </span>op { </div>
+<div class="line"><a name="l00071"></a><span class="lineno"> 71</span>  GLM_FUNC_QUALIFIER <span class="keywordtype">void</span> operator() (T& <a class="code" href="a00162.html#ga4b7956eb6e2fbedfc7cf2e46e85c5139">e</a>, T& t) { e = t; } </div>
+<div class="line"><a name="l00072"></a><span class="lineno"> 72</span>  };</div>
+<div class="line"><a name="l00073"></a><span class="lineno"> 73</span>  _apply_op(that, op());</div>
+<div class="line"><a name="l00074"></a><span class="lineno"> 74</span>  <span class="keywordflow">return</span> *<span class="keyword">this</span>;</div>
+<div class="line"><a name="l00075"></a><span class="lineno"> 75</span>  }</div>
+<div class="line"><a name="l00076"></a><span class="lineno"> 76</span> </div>
+<div class="line"><a name="l00077"></a><span class="lineno"> 77</span>  GLM_FUNC_QUALIFIER <span class="keywordtype">void</span> operator -= (vecType<T, P> <span class="keyword">const</span>& that)</div>
+<div class="line"><a name="l00078"></a><span class="lineno"> 78</span>  {</div>
+<div class="line"><a name="l00079"></a><span class="lineno"> 79</span>  <span class="keyword">struct </span>op { </div>
+<div class="line"><a name="l00080"></a><span class="lineno"> 80</span>  GLM_FUNC_QUALIFIER <span class="keywordtype">void</span> operator() (T& <a class="code" href="a00162.html#ga4b7956eb6e2fbedfc7cf2e46e85c5139">e</a>, T& t) { e -= t; } </div>
+<div class="line"><a name="l00081"></a><span class="lineno"> 81</span>  };</div>
+<div class="line"><a name="l00082"></a><span class="lineno"> 82</span>  _apply_op(that, op());</div>
+<div class="line"><a name="l00083"></a><span class="lineno"> 83</span>  }</div>
+<div class="line"><a name="l00084"></a><span class="lineno"> 84</span> </div>
+<div class="line"><a name="l00085"></a><span class="lineno"> 85</span>  GLM_FUNC_QUALIFIER <span class="keywordtype">void</span> operator += (vecType<T, P> <span class="keyword">const</span>& that)</div>
+<div class="line"><a name="l00086"></a><span class="lineno"> 86</span>  {</div>
+<div class="line"><a name="l00087"></a><span class="lineno"> 87</span>  <span class="keyword">struct </span>op { </div>
+<div class="line"><a name="l00088"></a><span class="lineno"> 88</span>  GLM_FUNC_QUALIFIER <span class="keywordtype">void</span> operator() (T& <a class="code" href="a00162.html#ga4b7956eb6e2fbedfc7cf2e46e85c5139">e</a>, T& t) { e += t; } </div>
+<div class="line"><a name="l00089"></a><span class="lineno"> 89</span>  };</div>
+<div class="line"><a name="l00090"></a><span class="lineno"> 90</span>  _apply_op(that, op());</div>
+<div class="line"><a name="l00091"></a><span class="lineno"> 91</span>  }</div>
+<div class="line"><a name="l00092"></a><span class="lineno"> 92</span> </div>
+<div class="line"><a name="l00093"></a><span class="lineno"> 93</span>  GLM_FUNC_QUALIFIER <span class="keywordtype">void</span> operator *= (vecType<T, P> <span class="keyword">const</span>& that)</div>
+<div class="line"><a name="l00094"></a><span class="lineno"> 94</span>  {</div>
+<div class="line"><a name="l00095"></a><span class="lineno"> 95</span>  <span class="keyword">struct </span>op { </div>
+<div class="line"><a name="l00096"></a><span class="lineno"> 96</span>  GLM_FUNC_QUALIFIER <span class="keywordtype">void</span> operator() (T& <a class="code" href="a00162.html#ga4b7956eb6e2fbedfc7cf2e46e85c5139">e</a>, T& t) { e *= t; } </div>
+<div class="line"><a name="l00097"></a><span class="lineno"> 97</span>  };</div>
+<div class="line"><a name="l00098"></a><span class="lineno"> 98</span>  _apply_op(that, op());</div>
+<div class="line"><a name="l00099"></a><span class="lineno"> 99</span>  }</div>
+<div class="line"><a name="l00100"></a><span class="lineno"> 100</span> </div>
+<div class="line"><a name="l00101"></a><span class="lineno"> 101</span>  GLM_FUNC_QUALIFIER <span class="keywordtype">void</span> operator /= (vecType<T, P> <span class="keyword">const</span>& that)</div>
+<div class="line"><a name="l00102"></a><span class="lineno"> 102</span>  {</div>
+<div class="line"><a name="l00103"></a><span class="lineno"> 103</span>  <span class="keyword">struct </span>op { </div>
+<div class="line"><a name="l00104"></a><span class="lineno"> 104</span>  GLM_FUNC_QUALIFIER <span class="keywordtype">void</span> operator() (T& <a class="code" href="a00162.html#ga4b7956eb6e2fbedfc7cf2e46e85c5139">e</a>, T& t) { e /= t; } </div>
+<div class="line"><a name="l00105"></a><span class="lineno"> 105</span>  };</div>
+<div class="line"><a name="l00106"></a><span class="lineno"> 106</span>  _apply_op(that, op());</div>
+<div class="line"><a name="l00107"></a><span class="lineno"> 107</span>  }</div>
+<div class="line"><a name="l00108"></a><span class="lineno"> 108</span> </div>
+<div class="line"><a name="l00109"></a><span class="lineno"> 109</span>  GLM_FUNC_QUALIFIER T& operator[](<span class="keywordtype">size_t</span> i)</div>
+<div class="line"><a name="l00110"></a><span class="lineno"> 110</span>  {</div>
+<div class="line"><a name="l00111"></a><span class="lineno"> 111</span>  <span class="keyword">const</span> <span class="keywordtype">int</span> offset_dst[4] = { E0, E1, E2, E3 };</div>
+<div class="line"><a name="l00112"></a><span class="lineno"> 112</span>  <span class="keywordflow">return</span> this->elem(offset_dst[i]);</div>
+<div class="line"><a name="l00113"></a><span class="lineno"> 113</span>  }</div>
+<div class="line"><a name="l00114"></a><span class="lineno"> 114</span>  GLM_FUNC_QUALIFIER T operator[](<span class="keywordtype">size_t</span> i)<span class="keyword"> const</span></div>
+<div class="line"><a name="l00115"></a><span class="lineno"> 115</span> <span class="keyword"> </span>{</div>
+<div class="line"><a name="l00116"></a><span class="lineno"> 116</span>  <span class="keyword">const</span> <span class="keywordtype">int</span> offset_dst[4] = { E0, E1, E2, E3 };</div>
+<div class="line"><a name="l00117"></a><span class="lineno"> 117</span>  <span class="keywordflow">return</span> this->elem(offset_dst[i]);</div>
+<div class="line"><a name="l00118"></a><span class="lineno"> 118</span>  }</div>
+<div class="line"><a name="l00119"></a><span class="lineno"> 119</span> </div>
+<div class="line"><a name="l00120"></a><span class="lineno"> 120</span>  <span class="keyword">protected</span>:</div>
+<div class="line"><a name="l00121"></a><span class="lineno"> 121</span>  <span class="keyword">template</span> <<span class="keyword">typename</span> U></div>
+<div class="line"><a name="l00122"></a><span class="lineno"> 122</span>  GLM_FUNC_QUALIFIER <span class="keywordtype">void</span> _apply_op(vecType<T, P> <span class="keyword">const</span>& that, U op)</div>
+<div class="line"><a name="l00123"></a><span class="lineno"> 123</span>  {</div>
+<div class="line"><a name="l00124"></a><span class="lineno"> 124</span>  <span class="comment">// Make a copy of the data in this == &that.</span></div>
+<div class="line"><a name="l00125"></a><span class="lineno"> 125</span>  <span class="comment">// The copier should optimize out the copy in cases where the function is</span></div>
+<div class="line"><a name="l00126"></a><span class="lineno"> 126</span>  <span class="comment">// properly inlined and the copy is not necessary.</span></div>
+<div class="line"><a name="l00127"></a><span class="lineno"> 127</span>  T t[N];</div>
+<div class="line"><a name="l00128"></a><span class="lineno"> 128</span>  <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < N; ++i)</div>
+<div class="line"><a name="l00129"></a><span class="lineno"> 129</span>  t[i] = that[i];</div>
+<div class="line"><a name="l00130"></a><span class="lineno"> 130</span>  <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < N; ++i)</div>
+<div class="line"><a name="l00131"></a><span class="lineno"> 131</span>  op( (*<span class="keyword">this</span>)[i], t[i] );</div>
+<div class="line"><a name="l00132"></a><span class="lineno"> 132</span>  }</div>
+<div class="line"><a name="l00133"></a><span class="lineno"> 133</span>  };</div>
+<div class="line"><a name="l00134"></a><span class="lineno"> 134</span> </div>
+<div class="line"><a name="l00135"></a><span class="lineno"> 135</span>  <span class="comment">// Specialization for swizzles containing duplicate elements. These cannot be modified.</span></div>
+<div class="line"><a name="l00136"></a><span class="lineno"> 136</span>  <span class="keyword">template</span> <<span class="keywordtype">int</span> N, <span class="keyword">typename</span> T, precision P, <span class="keyword">template</span> <<span class="keyword">typename</span>, precision> <span class="keyword">class </span>vecType, <span class="keywordtype">int</span> E0, <span class="keywordtype">int</span> E1, <span class="keywordtype">int</span> E2, <span class="keywordtype">int</span> E3></div>
+<div class="line"><a name="l00137"></a><span class="lineno"> 137</span>  <span class="keyword">struct </span>_swizzle_base2<N, T, P, vecType, E0,E1,E2,E3, 1> : <span class="keyword">public</span> _swizzle_base1<N, T, P, vecType, E0,E1,E2,E3, detail::is_aligned<P>::value></div>
+<div class="line"><a name="l00138"></a><span class="lineno"> 138</span>  {</div>
+<div class="line"><a name="l00139"></a><span class="lineno"> 139</span>  <span class="keyword">struct </span>Stub {};</div>
+<div class="line"><a name="l00140"></a><span class="lineno"> 140</span> </div>
+<div class="line"><a name="l00141"></a><span class="lineno"> 141</span>  GLM_FUNC_QUALIFIER _swizzle_base2& operator= (Stub <span class="keyword">const</span> &) { <span class="keywordflow">return</span> *<span class="keyword">this</span>; }</div>
+<div class="line"><a name="l00142"></a><span class="lineno"> 142</span> </div>
+<div class="line"><a name="l00143"></a><span class="lineno"> 143</span>  GLM_FUNC_QUALIFIER T operator[] (<span class="keywordtype">size_t</span> i)<span class="keyword"> const</span></div>
+<div class="line"><a name="l00144"></a><span class="lineno"> 144</span> <span class="keyword"> </span>{</div>
+<div class="line"><a name="l00145"></a><span class="lineno"> 145</span>  <span class="keyword">const</span> <span class="keywordtype">int</span> offset_dst[4] = { E0, E1, E2, E3 };</div>
+<div class="line"><a name="l00146"></a><span class="lineno"> 146</span>  <span class="keywordflow">return</span> this->elem(offset_dst[i]);</div>
+<div class="line"><a name="l00147"></a><span class="lineno"> 147</span>  }</div>
+<div class="line"><a name="l00148"></a><span class="lineno"> 148</span>  };</div>
+<div class="line"><a name="l00149"></a><span class="lineno"> 149</span> </div>
+<div class="line"><a name="l00150"></a><span class="lineno"> 150</span>  <span class="keyword">template</span> <<span class="keywordtype">int</span> N, <span class="keyword">typename</span> T, precision P, <span class="keyword">template</span> <<span class="keyword">typename</span>, precision> <span class="keyword">class </span>vecType, <span class="keywordtype">int</span> E0, <span class="keywordtype">int</span> E1, <span class="keywordtype">int</span> E2, <span class="keywordtype">int</span> E3></div>
+<div class="line"><a name="l00151"></a><span class="lineno"> 151</span>  <span class="keyword">struct </span>_swizzle : <span class="keyword">public</span> _swizzle_base2<N, T, P, vecType, E0, E1, E2, E3, (E0 == E1 || E0 == E2 || E0 == E3 || E1 == E2 || E1 == E3 || E2 == E3)></div>
+<div class="line"><a name="l00152"></a><span class="lineno"> 152</span>  {</div>
+<div class="line"><a name="l00153"></a><span class="lineno"> 153</span>  <span class="keyword">typedef</span> _swizzle_base2<N, T, P, vecType, E0, E1, E2, E3, (E0 == E1 || E0 == E2 || E0 == E3 || E1 == E2 || E1 == E3 || E2 == E3)> base_type;</div>
+<div class="line"><a name="l00154"></a><span class="lineno"> 154</span> </div>
+<div class="line"><a name="l00155"></a><span class="lineno"> 155</span>  <span class="keyword">using</span> base_type::operator=;</div>
+<div class="line"><a name="l00156"></a><span class="lineno"> 156</span> </div>
+<div class="line"><a name="l00157"></a><span class="lineno"> 157</span>  GLM_FUNC_QUALIFIER <span class="keyword">operator</span> vecType<T, P> () <span class="keyword">const</span> { <span class="keywordflow">return</span> (*<span class="keyword">this</span>)(); }</div>
+<div class="line"><a name="l00158"></a><span class="lineno"> 158</span>  };</div>
+<div class="line"><a name="l00159"></a><span class="lineno"> 159</span> </div>
+<div class="line"><a name="l00160"></a><span class="lineno"> 160</span> <span class="comment">//</span></div>
+<div class="line"><a name="l00161"></a><span class="lineno"> 161</span> <span class="comment">// To prevent the C++ syntax from getting entirely overwhelming, define some alias macros</span></div>
+<div class="line"><a name="l00162"></a><span class="lineno"> 162</span> <span class="comment">//</span></div>
+<div class="line"><a name="l00163"></a><span class="lineno"> 163</span> <span class="preprocessor">#define _GLM_SWIZZLE_TEMPLATE1 template <int N, typename T, precision P, template <typename, precision> class vecType, int E0, int E1, int E2, int E3></span></div>
+<div class="line"><a name="l00164"></a><span class="lineno"> 164</span> <span class="preprocessor">#define _GLM_SWIZZLE_TEMPLATE2 template <int N, typename T, precision P, template <typename, precision> class vecType, int E0, int E1, int E2, int E3, int F0, int F1, int F2, int F3></span></div>
+<div class="line"><a name="l00165"></a><span class="lineno"> 165</span> <span class="preprocessor">#define _GLM_SWIZZLE_TYPE1 _swizzle<N, T, P, vecType, E0, E1, E2, E3></span></div>
+<div class="line"><a name="l00166"></a><span class="lineno"> 166</span> <span class="preprocessor">#define _GLM_SWIZZLE_TYPE2 _swizzle<N, T, P, vecType, F0, F1, F2, F3></span></div>
+<div class="line"><a name="l00167"></a><span class="lineno"> 167</span> </div>
+<div class="line"><a name="l00168"></a><span class="lineno"> 168</span> <span class="comment">//</span></div>
+<div class="line"><a name="l00169"></a><span class="lineno"> 169</span> <span class="comment">// Wrapper for a binary operator (e.g. u.yy + v.zy)</span></div>
+<div class="line"><a name="l00170"></a><span class="lineno"> 170</span> <span class="comment">//</span></div>
+<div class="line"><a name="l00171"></a><span class="lineno"> 171</span> <span class="preprocessor">#define _GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(OPERAND) \</span></div>
+<div class="line"><a name="l00172"></a><span class="lineno"> 172</span> <span class="preprocessor"> _GLM_SWIZZLE_TEMPLATE2 \</span></div>
+<div class="line"><a name="l00173"></a><span class="lineno"> 173</span> <span class="preprocessor"> GLM_FUNC_QUALIFIER vecType<T, P> operator OPERAND ( const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE2& b) \</span></div>
+<div class="line"><a name="l00174"></a><span class="lineno"> 174</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00175"></a><span class="lineno"> 175</span> <span class="preprocessor"> return a() OPERAND b(); \</span></div>
+<div class="line"><a name="l00176"></a><span class="lineno"> 176</span> <span class="preprocessor"> } \</span></div>
+<div class="line"><a name="l00177"></a><span class="lineno"> 177</span> <span class="preprocessor"> _GLM_SWIZZLE_TEMPLATE1 \</span></div>
+<div class="line"><a name="l00178"></a><span class="lineno"> 178</span> <span class="preprocessor"> GLM_FUNC_QUALIFIER vecType<T, P> operator OPERAND ( const _GLM_SWIZZLE_TYPE1& a, const vecType<T, P>& b) \</span></div>
+<div class="line"><a name="l00179"></a><span class="lineno"> 179</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00180"></a><span class="lineno"> 180</span> <span class="preprocessor"> return a() OPERAND b; \</span></div>
+<div class="line"><a name="l00181"></a><span class="lineno"> 181</span> <span class="preprocessor"> } \</span></div>
+<div class="line"><a name="l00182"></a><span class="lineno"> 182</span> <span class="preprocessor"> _GLM_SWIZZLE_TEMPLATE1 \</span></div>
+<div class="line"><a name="l00183"></a><span class="lineno"> 183</span> <span class="preprocessor"> GLM_FUNC_QUALIFIER vecType<T, P> operator OPERAND ( const vecType<T, P>& a, const _GLM_SWIZZLE_TYPE1& b) \</span></div>
+<div class="line"><a name="l00184"></a><span class="lineno"> 184</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00185"></a><span class="lineno"> 185</span> <span class="preprocessor"> return a OPERAND b(); \</span></div>
+<div class="line"><a name="l00186"></a><span class="lineno"> 186</span> <span class="preprocessor"> }</span></div>
+<div class="line"><a name="l00187"></a><span class="lineno"> 187</span> </div>
+<div class="line"><a name="l00188"></a><span class="lineno"> 188</span> <span class="comment">//</span></div>
+<div class="line"><a name="l00189"></a><span class="lineno"> 189</span> <span class="comment">// Wrapper for a operand between a swizzle and a binary (e.g. 1.0f - u.xyz)</span></div>
+<div class="line"><a name="l00190"></a><span class="lineno"> 190</span> <span class="comment">//</span></div>
+<div class="line"><a name="l00191"></a><span class="lineno"> 191</span> <span class="preprocessor">#define _GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(OPERAND) \</span></div>
+<div class="line"><a name="l00192"></a><span class="lineno"> 192</span> <span class="preprocessor"> _GLM_SWIZZLE_TEMPLATE1 \</span></div>
+<div class="line"><a name="l00193"></a><span class="lineno"> 193</span> <span class="preprocessor"> GLM_FUNC_QUALIFIER vecType<T, P> operator OPERAND ( const _GLM_SWIZZLE_TYPE1& a, const T& b) \</span></div>
+<div class="line"><a name="l00194"></a><span class="lineno"> 194</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00195"></a><span class="lineno"> 195</span> <span class="preprocessor"> return a() OPERAND b; \</span></div>
+<div class="line"><a name="l00196"></a><span class="lineno"> 196</span> <span class="preprocessor"> } \</span></div>
+<div class="line"><a name="l00197"></a><span class="lineno"> 197</span> <span class="preprocessor"> _GLM_SWIZZLE_TEMPLATE1 \</span></div>
+<div class="line"><a name="l00198"></a><span class="lineno"> 198</span> <span class="preprocessor"> GLM_FUNC_QUALIFIER vecType<T, P> operator OPERAND ( const T& a, const _GLM_SWIZZLE_TYPE1& b) \</span></div>
+<div class="line"><a name="l00199"></a><span class="lineno"> 199</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00200"></a><span class="lineno"> 200</span> <span class="preprocessor"> return a OPERAND b(); \</span></div>
+<div class="line"><a name="l00201"></a><span class="lineno"> 201</span> <span class="preprocessor"> }</span></div>
+<div class="line"><a name="l00202"></a><span class="lineno"> 202</span> </div>
+<div class="line"><a name="l00203"></a><span class="lineno"> 203</span> <span class="comment">//</span></div>
+<div class="line"><a name="l00204"></a><span class="lineno"> 204</span> <span class="comment">// Macro for wrapping a function taking one argument (e.g. abs())</span></div>
+<div class="line"><a name="l00205"></a><span class="lineno"> 205</span> <span class="comment">//</span></div>
+<div class="line"><a name="l00206"></a><span class="lineno"> 206</span> <span class="preprocessor">#define _GLM_SWIZZLE_FUNCTION_1_ARGS(RETURN_TYPE,FUNCTION) \</span></div>
+<div class="line"><a name="l00207"></a><span class="lineno"> 207</span> <span class="preprocessor"> _GLM_SWIZZLE_TEMPLATE1 \</span></div>
+<div class="line"><a name="l00208"></a><span class="lineno"> 208</span> <span class="preprocessor"> GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a) \</span></div>
+<div class="line"><a name="l00209"></a><span class="lineno"> 209</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00210"></a><span class="lineno"> 210</span> <span class="preprocessor"> return FUNCTION(a()); \</span></div>
+<div class="line"><a name="l00211"></a><span class="lineno"> 211</span> <span class="preprocessor"> }</span></div>
+<div class="line"><a name="l00212"></a><span class="lineno"> 212</span> </div>
+<div class="line"><a name="l00213"></a><span class="lineno"> 213</span> <span class="comment">//</span></div>
+<div class="line"><a name="l00214"></a><span class="lineno"> 214</span> <span class="comment">// Macro for wrapping a function taking two vector arguments (e.g. dot()).</span></div>
+<div class="line"><a name="l00215"></a><span class="lineno"> 215</span> <span class="comment">//</span></div>
+<div class="line"><a name="l00216"></a><span class="lineno"> 216</span> <span class="preprocessor">#define _GLM_SWIZZLE_FUNCTION_2_ARGS(RETURN_TYPE,FUNCTION) \</span></div>
+<div class="line"><a name="l00217"></a><span class="lineno"> 217</span> <span class="preprocessor"> _GLM_SWIZZLE_TEMPLATE2 \</span></div>
+<div class="line"><a name="l00218"></a><span class="lineno"> 218</span> <span class="preprocessor"> GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE2& b) \</span></div>
+<div class="line"><a name="l00219"></a><span class="lineno"> 219</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00220"></a><span class="lineno"> 220</span> <span class="preprocessor"> return FUNCTION(a(), b()); \</span></div>
+<div class="line"><a name="l00221"></a><span class="lineno"> 221</span> <span class="preprocessor"> } \</span></div>
+<div class="line"><a name="l00222"></a><span class="lineno"> 222</span> <span class="preprocessor"> _GLM_SWIZZLE_TEMPLATE1 \</span></div>
+<div class="line"><a name="l00223"></a><span class="lineno"> 223</span> <span class="preprocessor"> GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE1& b) \</span></div>
+<div class="line"><a name="l00224"></a><span class="lineno"> 224</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00225"></a><span class="lineno"> 225</span> <span class="preprocessor"> return FUNCTION(a(), b()); \</span></div>
+<div class="line"><a name="l00226"></a><span class="lineno"> 226</span> <span class="preprocessor"> } \</span></div>
+<div class="line"><a name="l00227"></a><span class="lineno"> 227</span> <span class="preprocessor"> _GLM_SWIZZLE_TEMPLATE1 \</span></div>
+<div class="line"><a name="l00228"></a><span class="lineno"> 228</span> <span class="preprocessor"> GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const typename V& b) \</span></div>
+<div class="line"><a name="l00229"></a><span class="lineno"> 229</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00230"></a><span class="lineno"> 230</span> <span class="preprocessor"> return FUNCTION(a(), b); \</span></div>
+<div class="line"><a name="l00231"></a><span class="lineno"> 231</span> <span class="preprocessor"> } \</span></div>
+<div class="line"><a name="l00232"></a><span class="lineno"> 232</span> <span class="preprocessor"> _GLM_SWIZZLE_TEMPLATE1 \</span></div>
+<div class="line"><a name="l00233"></a><span class="lineno"> 233</span> <span class="preprocessor"> GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const V& a, const _GLM_SWIZZLE_TYPE1& b) \</span></div>
+<div class="line"><a name="l00234"></a><span class="lineno"> 234</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00235"></a><span class="lineno"> 235</span> <span class="preprocessor"> return FUNCTION(a, b()); \</span></div>
+<div class="line"><a name="l00236"></a><span class="lineno"> 236</span> <span class="preprocessor"> } </span></div>
+<div class="line"><a name="l00237"></a><span class="lineno"> 237</span> </div>
+<div class="line"><a name="l00238"></a><span class="lineno"> 238</span> <span class="comment">//</span></div>
+<div class="line"><a name="l00239"></a><span class="lineno"> 239</span> <span class="comment">// Macro for wrapping a function take 2 vec arguments followed by a scalar (e.g. mix()).</span></div>
+<div class="line"><a name="l00240"></a><span class="lineno"> 240</span> <span class="comment">//</span></div>
+<div class="line"><a name="l00241"></a><span class="lineno"> 241</span> <span class="preprocessor">#define _GLM_SWIZZLE_FUNCTION_2_ARGS_SCALAR(RETURN_TYPE,FUNCTION) \</span></div>
+<div class="line"><a name="l00242"></a><span class="lineno"> 242</span> <span class="preprocessor"> _GLM_SWIZZLE_TEMPLATE2 \</span></div>
+<div class="line"><a name="l00243"></a><span class="lineno"> 243</span> <span class="preprocessor"> GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE2& b, const T& c) \</span></div>
+<div class="line"><a name="l00244"></a><span class="lineno"> 244</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00245"></a><span class="lineno"> 245</span> <span class="preprocessor"> return FUNCTION(a(), b(), c); \</span></div>
+<div class="line"><a name="l00246"></a><span class="lineno"> 246</span> <span class="preprocessor"> } \</span></div>
+<div class="line"><a name="l00247"></a><span class="lineno"> 247</span> <span class="preprocessor"> _GLM_SWIZZLE_TEMPLATE1 \</span></div>
+<div class="line"><a name="l00248"></a><span class="lineno"> 248</span> <span class="preprocessor"> GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE1& b, const T& c) \</span></div>
+<div class="line"><a name="l00249"></a><span class="lineno"> 249</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00250"></a><span class="lineno"> 250</span> <span class="preprocessor"> return FUNCTION(a(), b(), c); \</span></div>
+<div class="line"><a name="l00251"></a><span class="lineno"> 251</span> <span class="preprocessor"> } \</span></div>
+<div class="line"><a name="l00252"></a><span class="lineno"> 252</span> <span class="preprocessor"> _GLM_SWIZZLE_TEMPLATE1 \</span></div>
+<div class="line"><a name="l00253"></a><span class="lineno"> 253</span> <span class="preprocessor"> GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const typename S0::vec_type& b, const T& c)\</span></div>
+<div class="line"><a name="l00254"></a><span class="lineno"> 254</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00255"></a><span class="lineno"> 255</span> <span class="preprocessor"> return FUNCTION(a(), b, c); \</span></div>
+<div class="line"><a name="l00256"></a><span class="lineno"> 256</span> <span class="preprocessor"> } \</span></div>
+<div class="line"><a name="l00257"></a><span class="lineno"> 257</span> <span class="preprocessor"> _GLM_SWIZZLE_TEMPLATE1 \</span></div>
+<div class="line"><a name="l00258"></a><span class="lineno"> 258</span> <span class="preprocessor"> GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const typename V& a, const _GLM_SWIZZLE_TYPE1& b, const T& c) \</span></div>
+<div class="line"><a name="l00259"></a><span class="lineno"> 259</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00260"></a><span class="lineno"> 260</span> <span class="preprocessor"> return FUNCTION(a, b(), c); \</span></div>
+<div class="line"><a name="l00261"></a><span class="lineno"> 261</span> <span class="preprocessor"> } </span></div>
+<div class="line"><a name="l00262"></a><span class="lineno"> 262</span>  </div>
+<div class="line"><a name="l00263"></a><span class="lineno"> 263</span> }<span class="comment">//namespace detail </span></div>
+<div class="line"><a name="l00264"></a><span class="lineno"> 264</span> }<span class="comment">//namespace glm</span></div>
+<div class="line"><a name="l00265"></a><span class="lineno"> 265</span> </div>
+<div class="line"><a name="l00266"></a><span class="lineno"> 266</span> <span class="keyword">namespace </span><a class="code" href="a00141.html">glm</a></div>
+<div class="line"><a name="l00267"></a><span class="lineno"> 267</span> {</div>
+<div class="line"><a name="l00268"></a><span class="lineno"> 268</span>  <span class="keyword">namespace </span>detail</div>
+<div class="line"><a name="l00269"></a><span class="lineno"> 269</span>  {</div>
+<div class="line"><a name="l00270"></a><span class="lineno"> 270</span>  _GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(-)</div>
+<div class="line"><a name="l00271"></a><span class="lineno"> 271</span>  _GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(*)</div>
+<div class="line"><a name="l00272"></a><span class="lineno"> 272</span>  _GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(+)</div>
+<div class="line"><a name="l00273"></a><span class="lineno"> 273</span>  _GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(-)</div>
+<div class="line"><a name="l00274"></a><span class="lineno"> 274</span>  _GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(*)</div>
+<div class="line"><a name="l00275"></a><span class="lineno"> 275</span>  _GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(/)</div>
+<div class="line"><a name="l00276"></a><span class="lineno"> 276</span>  }</div>
+<div class="line"><a name="l00277"></a><span class="lineno"> 277</span> </div>
+<div class="line"><a name="l00278"></a><span class="lineno"> 278</span>  <span class="comment">//</span></div>
+<div class="line"><a name="l00279"></a><span class="lineno"> 279</span>  <span class="comment">// Swizzles are distinct types from the unswizzled type. The below macros will</span></div>
+<div class="line"><a name="l00280"></a><span class="lineno"> 280</span>  <span class="comment">// provide template specializations for the swizzle types for the given functions</span></div>
+<div class="line"><a name="l00281"></a><span class="lineno"> 281</span>  <span class="comment">// so that the compiler does not have any ambiguity to choosing how to handle</span></div>
+<div class="line"><a name="l00282"></a><span class="lineno"> 282</span>  <span class="comment">// the function.</span></div>
+<div class="line"><a name="l00283"></a><span class="lineno"> 283</span>  <span class="comment">//</span></div>
+<div class="line"><a name="l00284"></a><span class="lineno"> 284</span>  <span class="comment">// The alternative is to use the operator()() when calling the function in order</span></div>
+<div class="line"><a name="l00285"></a><span class="lineno"> 285</span>  <span class="comment">// to explicitly convert the swizzled type to the unswizzled type.</span></div>
+<div class="line"><a name="l00286"></a><span class="lineno"> 286</span>  <span class="comment">//</span></div>
+<div class="line"><a name="l00287"></a><span class="lineno"> 287</span> </div>
+<div class="line"><a name="l00288"></a><span class="lineno"> 288</span>  <span class="comment">//_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, abs);</span></div>
+<div class="line"><a name="l00289"></a><span class="lineno"> 289</span>  <span class="comment">//_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, acos);</span></div>
+<div class="line"><a name="l00290"></a><span class="lineno"> 290</span>  <span class="comment">//_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, acosh);</span></div>
+<div class="line"><a name="l00291"></a><span class="lineno"> 291</span>  <span class="comment">//_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, all);</span></div>
+<div class="line"><a name="l00292"></a><span class="lineno"> 292</span>  <span class="comment">//_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, any);</span></div>
+<div class="line"><a name="l00293"></a><span class="lineno"> 293</span> </div>
+<div class="line"><a name="l00294"></a><span class="lineno"> 294</span>  <span class="comment">//_GLM_SWIZZLE_FUNCTION_2_ARGS(value_type, dot);</span></div>
+<div class="line"><a name="l00295"></a><span class="lineno"> 295</span>  <span class="comment">//_GLM_SWIZZLE_FUNCTION_2_ARGS(vec_type, cross);</span></div>
+<div class="line"><a name="l00296"></a><span class="lineno"> 296</span>  <span class="comment">//_GLM_SWIZZLE_FUNCTION_2_ARGS(vec_type, step); </span></div>
+<div class="line"><a name="l00297"></a><span class="lineno"> 297</span>  <span class="comment">//_GLM_SWIZZLE_FUNCTION_2_ARGS_SCALAR(vec_type, mix);</span></div>
+<div class="line"><a name="l00298"></a><span class="lineno"> 298</span> }</div>
+<div class="line"><a name="l00299"></a><span class="lineno"> 299</span> </div>
+<div class="line"><a name="l00300"></a><span class="lineno"> 300</span> <span class="preprocessor">#define _GLM_SWIZZLE2_2_MEMBERS(T, P, V, E0,E1) \</span></div>
+<div class="line"><a name="l00301"></a><span class="lineno"> 301</span> <span class="preprocessor"> struct { detail::_swizzle<2, T, P, V, 0,0,-1,-2> E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00302"></a><span class="lineno"> 302</span> <span class="preprocessor"> struct { detail::_swizzle<2, T, P, V, 0,1,-1,-2> E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00303"></a><span class="lineno"> 303</span> <span class="preprocessor"> struct { detail::_swizzle<2, T, P, V, 1,0,-1,-2> E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00304"></a><span class="lineno"> 304</span> <span class="preprocessor"> struct { detail::_swizzle<2, T, P, V, 1,1,-1,-2> E1 ## E1; }; </span></div>
+<div class="line"><a name="l00305"></a><span class="lineno"> 305</span> </div>
+<div class="line"><a name="l00306"></a><span class="lineno"> 306</span> <span class="preprocessor">#define _GLM_SWIZZLE2_3_MEMBERS(T, P, V, E0,E1) \</span></div>
+<div class="line"><a name="l00307"></a><span class="lineno"> 307</span> <span class="preprocessor"> struct { detail::_swizzle<3,T, P, V, 0,0,0,-1> E0 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00308"></a><span class="lineno"> 308</span> <span class="preprocessor"> struct { detail::_swizzle<3,T, P, V, 0,0,1,-1> E0 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00309"></a><span class="lineno"> 309</span> <span class="preprocessor"> struct { detail::_swizzle<3,T, P, V, 0,1,0,-1> E0 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00310"></a><span class="lineno"> 310</span> <span class="preprocessor"> struct { detail::_swizzle<3,T, P, V, 0,1,1,-1> E0 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00311"></a><span class="lineno"> 311</span> <span class="preprocessor"> struct { detail::_swizzle<3,T, P, V, 1,0,0,-1> E1 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00312"></a><span class="lineno"> 312</span> <span class="preprocessor"> struct { detail::_swizzle<3,T, P, V, 1,0,1,-1> E1 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00313"></a><span class="lineno"> 313</span> <span class="preprocessor"> struct { detail::_swizzle<3,T, P, V, 1,1,0,-1> E1 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00314"></a><span class="lineno"> 314</span> <span class="preprocessor"> struct { detail::_swizzle<3,T, P, V, 1,1,1,-1> E1 ## E1 ## E1; }; </span></div>
+<div class="line"><a name="l00315"></a><span class="lineno"> 315</span> </div>
+<div class="line"><a name="l00316"></a><span class="lineno"> 316</span> <span class="preprocessor">#define _GLM_SWIZZLE2_4_MEMBERS(T, P, V, E0,E1) \</span></div>
+<div class="line"><a name="l00317"></a><span class="lineno"> 317</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00318"></a><span class="lineno"> 318</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00319"></a><span class="lineno"> 319</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00320"></a><span class="lineno"> 320</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00321"></a><span class="lineno"> 321</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00322"></a><span class="lineno"> 322</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00323"></a><span class="lineno"> 323</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00324"></a><span class="lineno"> 324</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00325"></a><span class="lineno"> 325</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00326"></a><span class="lineno"> 326</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00327"></a><span class="lineno"> 327</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00328"></a><span class="lineno"> 328</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00329"></a><span class="lineno"> 329</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00330"></a><span class="lineno"> 330</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00331"></a><span class="lineno"> 331</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00332"></a><span class="lineno"> 332</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,1,1,1> E1 ## E1 ## E1 ## E1; };</span></div>
+<div class="line"><a name="l00333"></a><span class="lineno"> 333</span> </div>
+<div class="line"><a name="l00334"></a><span class="lineno"> 334</span> <span class="preprocessor">#define _GLM_SWIZZLE3_2_MEMBERS(T, P, V, E0,E1,E2) \</span></div>
+<div class="line"><a name="l00335"></a><span class="lineno"> 335</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 0,0,-1,-2> E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00336"></a><span class="lineno"> 336</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 0,1,-1,-2> E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00337"></a><span class="lineno"> 337</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 0,2,-1,-2> E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00338"></a><span class="lineno"> 338</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 1,0,-1,-2> E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00339"></a><span class="lineno"> 339</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 1,1,-1,-2> E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00340"></a><span class="lineno"> 340</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 1,2,-1,-2> E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00341"></a><span class="lineno"> 341</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 2,0,-1,-2> E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00342"></a><span class="lineno"> 342</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 2,1,-1,-2> E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00343"></a><span class="lineno"> 343</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 2,2,-1,-2> E2 ## E2; };</span></div>
+<div class="line"><a name="l00344"></a><span class="lineno"> 344</span> </div>
+<div class="line"><a name="l00345"></a><span class="lineno"> 345</span> <span class="preprocessor">#define _GLM_SWIZZLE3_3_MEMBERS(T, P, V ,E0,E1,E2) \</span></div>
+<div class="line"><a name="l00346"></a><span class="lineno"> 346</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,0,0,-1> E0 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00347"></a><span class="lineno"> 347</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,0,1,-1> E0 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00348"></a><span class="lineno"> 348</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,0,2,-1> E0 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00349"></a><span class="lineno"> 349</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,1,0,-1> E0 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00350"></a><span class="lineno"> 350</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,1,1,-1> E0 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00351"></a><span class="lineno"> 351</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,1,2,-1> E0 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00352"></a><span class="lineno"> 352</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,2,0,-1> E0 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00353"></a><span class="lineno"> 353</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,2,1,-1> E0 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00354"></a><span class="lineno"> 354</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,2,2,-1> E0 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00355"></a><span class="lineno"> 355</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,0,0,-1> E1 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00356"></a><span class="lineno"> 356</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,0,1,-1> E1 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00357"></a><span class="lineno"> 357</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,0,2,-1> E1 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00358"></a><span class="lineno"> 358</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,1,0,-1> E1 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00359"></a><span class="lineno"> 359</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,1,1,-1> E1 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00360"></a><span class="lineno"> 360</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,1,2,-1> E1 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00361"></a><span class="lineno"> 361</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,2,0,-1> E1 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00362"></a><span class="lineno"> 362</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,2,1,-1> E1 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00363"></a><span class="lineno"> 363</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,2,2,-1> E1 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00364"></a><span class="lineno"> 364</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,0,0,-1> E2 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00365"></a><span class="lineno"> 365</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,0,1,-1> E2 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00366"></a><span class="lineno"> 366</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,0,2,-1> E2 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00367"></a><span class="lineno"> 367</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,1,0,-1> E2 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00368"></a><span class="lineno"> 368</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,1,1,-1> E2 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00369"></a><span class="lineno"> 369</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,1,2,-1> E2 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00370"></a><span class="lineno"> 370</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,2,0,-1> E2 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00371"></a><span class="lineno"> 371</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,2,1,-1> E2 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00372"></a><span class="lineno"> 372</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,2,2,-1> E2 ## E2 ## E2; };</span></div>
+<div class="line"><a name="l00373"></a><span class="lineno"> 373</span> </div>
+<div class="line"><a name="l00374"></a><span class="lineno"> 374</span> <span class="preprocessor">#define _GLM_SWIZZLE3_4_MEMBERS(T, P, V, E0,E1,E2) \</span></div>
+<div class="line"><a name="l00375"></a><span class="lineno"> 375</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00376"></a><span class="lineno"> 376</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00377"></a><span class="lineno"> 377</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00378"></a><span class="lineno"> 378</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00379"></a><span class="lineno"> 379</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00380"></a><span class="lineno"> 380</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00381"></a><span class="lineno"> 381</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00382"></a><span class="lineno"> 382</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00383"></a><span class="lineno"> 383</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00384"></a><span class="lineno"> 384</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00385"></a><span class="lineno"> 385</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00386"></a><span class="lineno"> 386</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00387"></a><span class="lineno"> 387</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00388"></a><span class="lineno"> 388</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00389"></a><span class="lineno"> 389</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00390"></a><span class="lineno"> 390</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00391"></a><span class="lineno"> 391</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00392"></a><span class="lineno"> 392</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00393"></a><span class="lineno"> 393</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00394"></a><span class="lineno"> 394</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00395"></a><span class="lineno"> 395</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00396"></a><span class="lineno"> 396</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00397"></a><span class="lineno"> 397</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00398"></a><span class="lineno"> 398</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00399"></a><span class="lineno"> 399</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00400"></a><span class="lineno"> 400</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00401"></a><span class="lineno"> 401</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00402"></a><span class="lineno"> 402</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00403"></a><span class="lineno"> 403</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00404"></a><span class="lineno"> 404</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00405"></a><span class="lineno"> 405</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00406"></a><span class="lineno"> 406</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00407"></a><span class="lineno"> 407</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00408"></a><span class="lineno"> 408</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00409"></a><span class="lineno"> 409</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00410"></a><span class="lineno"> 410</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00411"></a><span class="lineno"> 411</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00412"></a><span class="lineno"> 412</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00413"></a><span class="lineno"> 413</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00414"></a><span class="lineno"> 414</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00415"></a><span class="lineno"> 415</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00416"></a><span class="lineno"> 416</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00417"></a><span class="lineno"> 417</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00418"></a><span class="lineno"> 418</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00419"></a><span class="lineno"> 419</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00420"></a><span class="lineno"> 420</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00421"></a><span class="lineno"> 421</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00422"></a><span class="lineno"> 422</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00423"></a><span class="lineno"> 423</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00424"></a><span class="lineno"> 424</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00425"></a><span class="lineno"> 425</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00426"></a><span class="lineno"> 426</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00427"></a><span class="lineno"> 427</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00428"></a><span class="lineno"> 428</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00429"></a><span class="lineno"> 429</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00430"></a><span class="lineno"> 430</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00431"></a><span class="lineno"> 431</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00432"></a><span class="lineno"> 432</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00433"></a><span class="lineno"> 433</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00434"></a><span class="lineno"> 434</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00435"></a><span class="lineno"> 435</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00436"></a><span class="lineno"> 436</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00437"></a><span class="lineno"> 437</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00438"></a><span class="lineno"> 438</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00439"></a><span class="lineno"> 439</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00440"></a><span class="lineno"> 440</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00441"></a><span class="lineno"> 441</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00442"></a><span class="lineno"> 442</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00443"></a><span class="lineno"> 443</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00444"></a><span class="lineno"> 444</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00445"></a><span class="lineno"> 445</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00446"></a><span class="lineno"> 446</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00447"></a><span class="lineno"> 447</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00448"></a><span class="lineno"> 448</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00449"></a><span class="lineno"> 449</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00450"></a><span class="lineno"> 450</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00451"></a><span class="lineno"> 451</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00452"></a><span class="lineno"> 452</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00453"></a><span class="lineno"> 453</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00454"></a><span class="lineno"> 454</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00455"></a><span class="lineno"> 455</span> <span class="preprocessor"> struct { detail::_swizzle<4,T, P, V, 2,2,2,2> E2 ## E2 ## E2 ## E2; }; </span></div>
+<div class="line"><a name="l00456"></a><span class="lineno"> 456</span> </div>
+<div class="line"><a name="l00457"></a><span class="lineno"> 457</span> <span class="preprocessor">#define _GLM_SWIZZLE4_2_MEMBERS(T, P, V, E0,E1,E2,E3) \</span></div>
+<div class="line"><a name="l00458"></a><span class="lineno"> 458</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 0,0,-1,-2> E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00459"></a><span class="lineno"> 459</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 0,1,-1,-2> E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00460"></a><span class="lineno"> 460</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 0,2,-1,-2> E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00461"></a><span class="lineno"> 461</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 0,3,-1,-2> E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00462"></a><span class="lineno"> 462</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 1,0,-1,-2> E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00463"></a><span class="lineno"> 463</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 1,1,-1,-2> E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00464"></a><span class="lineno"> 464</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 1,2,-1,-2> E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00465"></a><span class="lineno"> 465</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 1,3,-1,-2> E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00466"></a><span class="lineno"> 466</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 2,0,-1,-2> E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00467"></a><span class="lineno"> 467</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 2,1,-1,-2> E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00468"></a><span class="lineno"> 468</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 2,2,-1,-2> E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00469"></a><span class="lineno"> 469</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 2,3,-1,-2> E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00470"></a><span class="lineno"> 470</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 3,0,-1,-2> E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00471"></a><span class="lineno"> 471</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 3,1,-1,-2> E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00472"></a><span class="lineno"> 472</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 3,2,-1,-2> E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00473"></a><span class="lineno"> 473</span> <span class="preprocessor"> struct { detail::_swizzle<2,T, P, V, 3,3,-1,-2> E3 ## E3; }; </span></div>
+<div class="line"><a name="l00474"></a><span class="lineno"> 474</span> </div>
+<div class="line"><a name="l00475"></a><span class="lineno"> 475</span> <span class="preprocessor">#define _GLM_SWIZZLE4_3_MEMBERS(T, P, V, E0,E1,E2,E3) \</span></div>
+<div class="line"><a name="l00476"></a><span class="lineno"> 476</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,0,0,-1> E0 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00477"></a><span class="lineno"> 477</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,0,1,-1> E0 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00478"></a><span class="lineno"> 478</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,0,2,-1> E0 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00479"></a><span class="lineno"> 479</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,0,3,-1> E0 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00480"></a><span class="lineno"> 480</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,1,0,-1> E0 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00481"></a><span class="lineno"> 481</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,1,1,-1> E0 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00482"></a><span class="lineno"> 482</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,1,2,-1> E0 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00483"></a><span class="lineno"> 483</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,1,3,-1> E0 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00484"></a><span class="lineno"> 484</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,2,0,-1> E0 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00485"></a><span class="lineno"> 485</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,2,1,-1> E0 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00486"></a><span class="lineno"> 486</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,2,2,-1> E0 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00487"></a><span class="lineno"> 487</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,2,3,-1> E0 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00488"></a><span class="lineno"> 488</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,3,0,-1> E0 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00489"></a><span class="lineno"> 489</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,3,1,-1> E0 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00490"></a><span class="lineno"> 490</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,3,2,-1> E0 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00491"></a><span class="lineno"> 491</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 0,3,3,-1> E0 ## E3 ## E3; }; \</span></div>
+<div class="line"><a name="l00492"></a><span class="lineno"> 492</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,0,0,-1> E1 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00493"></a><span class="lineno"> 493</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,0,1,-1> E1 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00494"></a><span class="lineno"> 494</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,0,2,-1> E1 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00495"></a><span class="lineno"> 495</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,0,3,-1> E1 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00496"></a><span class="lineno"> 496</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,1,0,-1> E1 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00497"></a><span class="lineno"> 497</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,1,1,-1> E1 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00498"></a><span class="lineno"> 498</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,1,2,-1> E1 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00499"></a><span class="lineno"> 499</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,1,3,-1> E1 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00500"></a><span class="lineno"> 500</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,2,0,-1> E1 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00501"></a><span class="lineno"> 501</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,2,1,-1> E1 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00502"></a><span class="lineno"> 502</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,2,2,-1> E1 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00503"></a><span class="lineno"> 503</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,2,3,-1> E1 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00504"></a><span class="lineno"> 504</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,3,0,-1> E1 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00505"></a><span class="lineno"> 505</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,3,1,-1> E1 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00506"></a><span class="lineno"> 506</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,3,2,-1> E1 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00507"></a><span class="lineno"> 507</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 1,3,3,-1> E1 ## E3 ## E3; }; \</span></div>
+<div class="line"><a name="l00508"></a><span class="lineno"> 508</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,0,0,-1> E2 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00509"></a><span class="lineno"> 509</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,0,1,-1> E2 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00510"></a><span class="lineno"> 510</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,0,2,-1> E2 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00511"></a><span class="lineno"> 511</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,0,3,-1> E2 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00512"></a><span class="lineno"> 512</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,1,0,-1> E2 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00513"></a><span class="lineno"> 513</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,1,1,-1> E2 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00514"></a><span class="lineno"> 514</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,1,2,-1> E2 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00515"></a><span class="lineno"> 515</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,1,3,-1> E2 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00516"></a><span class="lineno"> 516</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,2,0,-1> E2 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00517"></a><span class="lineno"> 517</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,2,1,-1> E2 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00518"></a><span class="lineno"> 518</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,2,2,-1> E2 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00519"></a><span class="lineno"> 519</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,2,3,-1> E2 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00520"></a><span class="lineno"> 520</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,3,0,-1> E2 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00521"></a><span class="lineno"> 521</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,3,1,-1> E2 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00522"></a><span class="lineno"> 522</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,3,2,-1> E2 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00523"></a><span class="lineno"> 523</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 2,3,3,-1> E2 ## E3 ## E3; }; \</span></div>
+<div class="line"><a name="l00524"></a><span class="lineno"> 524</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 3,0,0,-1> E3 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00525"></a><span class="lineno"> 525</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 3,0,1,-1> E3 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00526"></a><span class="lineno"> 526</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 3,0,2,-1> E3 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00527"></a><span class="lineno"> 527</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 3,0,3,-1> E3 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00528"></a><span class="lineno"> 528</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 3,1,0,-1> E3 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00529"></a><span class="lineno"> 529</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 3,1,1,-1> E3 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00530"></a><span class="lineno"> 530</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 3,1,2,-1> E3 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00531"></a><span class="lineno"> 531</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 3,1,3,-1> E3 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00532"></a><span class="lineno"> 532</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 3,2,0,-1> E3 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00533"></a><span class="lineno"> 533</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 3,2,1,-1> E3 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00534"></a><span class="lineno"> 534</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 3,2,2,-1> E3 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00535"></a><span class="lineno"> 535</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 3,2,3,-1> E3 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00536"></a><span class="lineno"> 536</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 3,3,0,-1> E3 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00537"></a><span class="lineno"> 537</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 3,3,1,-1> E3 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00538"></a><span class="lineno"> 538</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 3,3,2,-1> E3 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00539"></a><span class="lineno"> 539</span> <span class="preprocessor"> struct { detail::_swizzle<3, T, P, V, 3,3,3,-1> E3 ## E3 ## E3; }; </span></div>
+<div class="line"><a name="l00540"></a><span class="lineno"> 540</span> </div>
+<div class="line"><a name="l00541"></a><span class="lineno"> 541</span> <span class="preprocessor">#define _GLM_SWIZZLE4_4_MEMBERS(T, P, V, E0,E1,E2,E3) \</span></div>
+<div class="line"><a name="l00542"></a><span class="lineno"> 542</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00543"></a><span class="lineno"> 543</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00544"></a><span class="lineno"> 544</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00545"></a><span class="lineno"> 545</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,0,0,3> E0 ## E0 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00546"></a><span class="lineno"> 546</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00547"></a><span class="lineno"> 547</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00548"></a><span class="lineno"> 548</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00549"></a><span class="lineno"> 549</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,0,1,3> E0 ## E0 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00550"></a><span class="lineno"> 550</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00551"></a><span class="lineno"> 551</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00552"></a><span class="lineno"> 552</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00553"></a><span class="lineno"> 553</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,0,2,3> E0 ## E0 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00554"></a><span class="lineno"> 554</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,0,3,0> E0 ## E0 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00555"></a><span class="lineno"> 555</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,0,3,1> E0 ## E0 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00556"></a><span class="lineno"> 556</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,0,3,2> E0 ## E0 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00557"></a><span class="lineno"> 557</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,0,3,3> E0 ## E0 ## E3 ## E3; }; \</span></div>
+<div class="line"><a name="l00558"></a><span class="lineno"> 558</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00559"></a><span class="lineno"> 559</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00560"></a><span class="lineno"> 560</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00561"></a><span class="lineno"> 561</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,1,0,3> E0 ## E1 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00562"></a><span class="lineno"> 562</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00563"></a><span class="lineno"> 563</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00564"></a><span class="lineno"> 564</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00565"></a><span class="lineno"> 565</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,1,1,3> E0 ## E1 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00566"></a><span class="lineno"> 566</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00567"></a><span class="lineno"> 567</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00568"></a><span class="lineno"> 568</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00569"></a><span class="lineno"> 569</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,1,2,3> E0 ## E1 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00570"></a><span class="lineno"> 570</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,1,3,0> E0 ## E1 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00571"></a><span class="lineno"> 571</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,1,3,1> E0 ## E1 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00572"></a><span class="lineno"> 572</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,1,3,2> E0 ## E1 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00573"></a><span class="lineno"> 573</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,1,3,3> E0 ## E1 ## E3 ## E3; }; \</span></div>
+<div class="line"><a name="l00574"></a><span class="lineno"> 574</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00575"></a><span class="lineno"> 575</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00576"></a><span class="lineno"> 576</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00577"></a><span class="lineno"> 577</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,2,0,3> E0 ## E2 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00578"></a><span class="lineno"> 578</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00579"></a><span class="lineno"> 579</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00580"></a><span class="lineno"> 580</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00581"></a><span class="lineno"> 581</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,2,1,3> E0 ## E2 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00582"></a><span class="lineno"> 582</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00583"></a><span class="lineno"> 583</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00584"></a><span class="lineno"> 584</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00585"></a><span class="lineno"> 585</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,2,2,3> E0 ## E2 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00586"></a><span class="lineno"> 586</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,2,3,0> E0 ## E2 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00587"></a><span class="lineno"> 587</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,2,3,1> E0 ## E2 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00588"></a><span class="lineno"> 588</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,2,3,2> E0 ## E2 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00589"></a><span class="lineno"> 589</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,2,3,3> E0 ## E2 ## E3 ## E3; }; \</span></div>
+<div class="line"><a name="l00590"></a><span class="lineno"> 590</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,3,0,0> E0 ## E3 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00591"></a><span class="lineno"> 591</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,3,0,1> E0 ## E3 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00592"></a><span class="lineno"> 592</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,3,0,2> E0 ## E3 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00593"></a><span class="lineno"> 593</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,3,0,3> E0 ## E3 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00594"></a><span class="lineno"> 594</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,3,1,0> E0 ## E3 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00595"></a><span class="lineno"> 595</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,3,1,1> E0 ## E3 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00596"></a><span class="lineno"> 596</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,3,1,2> E0 ## E3 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00597"></a><span class="lineno"> 597</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,3,1,3> E0 ## E3 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00598"></a><span class="lineno"> 598</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,3,2,0> E0 ## E3 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00599"></a><span class="lineno"> 599</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,3,2,1> E0 ## E3 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00600"></a><span class="lineno"> 600</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,3,2,2> E0 ## E3 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00601"></a><span class="lineno"> 601</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,3,2,3> E0 ## E3 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00602"></a><span class="lineno"> 602</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,3,3,0> E0 ## E3 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00603"></a><span class="lineno"> 603</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,3,3,1> E0 ## E3 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00604"></a><span class="lineno"> 604</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,3,3,2> E0 ## E3 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00605"></a><span class="lineno"> 605</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 0,3,3,3> E0 ## E3 ## E3 ## E3; }; \</span></div>
+<div class="line"><a name="l00606"></a><span class="lineno"> 606</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00607"></a><span class="lineno"> 607</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00608"></a><span class="lineno"> 608</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00609"></a><span class="lineno"> 609</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,0,0,3> E1 ## E0 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00610"></a><span class="lineno"> 610</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00611"></a><span class="lineno"> 611</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00612"></a><span class="lineno"> 612</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00613"></a><span class="lineno"> 613</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,0,1,3> E1 ## E0 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00614"></a><span class="lineno"> 614</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00615"></a><span class="lineno"> 615</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00616"></a><span class="lineno"> 616</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00617"></a><span class="lineno"> 617</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,0,2,3> E1 ## E0 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00618"></a><span class="lineno"> 618</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,0,3,0> E1 ## E0 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00619"></a><span class="lineno"> 619</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,0,3,1> E1 ## E0 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00620"></a><span class="lineno"> 620</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,0,3,2> E1 ## E0 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00621"></a><span class="lineno"> 621</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,0,3,3> E1 ## E0 ## E3 ## E3; }; \</span></div>
+<div class="line"><a name="l00622"></a><span class="lineno"> 622</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00623"></a><span class="lineno"> 623</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00624"></a><span class="lineno"> 624</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00625"></a><span class="lineno"> 625</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,1,0,3> E1 ## E1 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00626"></a><span class="lineno"> 626</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00627"></a><span class="lineno"> 627</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00628"></a><span class="lineno"> 628</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00629"></a><span class="lineno"> 629</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,1,1,3> E1 ## E1 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00630"></a><span class="lineno"> 630</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00631"></a><span class="lineno"> 631</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00632"></a><span class="lineno"> 632</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00633"></a><span class="lineno"> 633</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,1,2,3> E1 ## E1 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00634"></a><span class="lineno"> 634</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,1,3,0> E1 ## E1 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00635"></a><span class="lineno"> 635</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,1,3,1> E1 ## E1 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00636"></a><span class="lineno"> 636</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,1,3,2> E1 ## E1 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00637"></a><span class="lineno"> 637</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,1,3,3> E1 ## E1 ## E3 ## E3; }; \</span></div>
+<div class="line"><a name="l00638"></a><span class="lineno"> 638</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00639"></a><span class="lineno"> 639</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00640"></a><span class="lineno"> 640</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00641"></a><span class="lineno"> 641</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,2,0,3> E1 ## E2 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00642"></a><span class="lineno"> 642</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00643"></a><span class="lineno"> 643</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00644"></a><span class="lineno"> 644</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00645"></a><span class="lineno"> 645</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,2,1,3> E1 ## E2 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00646"></a><span class="lineno"> 646</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00647"></a><span class="lineno"> 647</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00648"></a><span class="lineno"> 648</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00649"></a><span class="lineno"> 649</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,2,2,3> E1 ## E2 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00650"></a><span class="lineno"> 650</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,2,3,0> E1 ## E2 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00651"></a><span class="lineno"> 651</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,2,3,1> E1 ## E2 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00652"></a><span class="lineno"> 652</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,2,3,2> E1 ## E2 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00653"></a><span class="lineno"> 653</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,2,3,3> E1 ## E2 ## E3 ## E3; }; \</span></div>
+<div class="line"><a name="l00654"></a><span class="lineno"> 654</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,3,0,0> E1 ## E3 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00655"></a><span class="lineno"> 655</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,3,0,1> E1 ## E3 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00656"></a><span class="lineno"> 656</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,3,0,2> E1 ## E3 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00657"></a><span class="lineno"> 657</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,3,0,3> E1 ## E3 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00658"></a><span class="lineno"> 658</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,3,1,0> E1 ## E3 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00659"></a><span class="lineno"> 659</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,3,1,1> E1 ## E3 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00660"></a><span class="lineno"> 660</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,3,1,2> E1 ## E3 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00661"></a><span class="lineno"> 661</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,3,1,3> E1 ## E3 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00662"></a><span class="lineno"> 662</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,3,2,0> E1 ## E3 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00663"></a><span class="lineno"> 663</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,3,2,1> E1 ## E3 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00664"></a><span class="lineno"> 664</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,3,2,2> E1 ## E3 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00665"></a><span class="lineno"> 665</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,3,2,3> E1 ## E3 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00666"></a><span class="lineno"> 666</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,3,3,0> E1 ## E3 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00667"></a><span class="lineno"> 667</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,3,3,1> E1 ## E3 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00668"></a><span class="lineno"> 668</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,3,3,2> E1 ## E3 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00669"></a><span class="lineno"> 669</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 1,3,3,3> E1 ## E3 ## E3 ## E3; }; \</span></div>
+<div class="line"><a name="l00670"></a><span class="lineno"> 670</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00671"></a><span class="lineno"> 671</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00672"></a><span class="lineno"> 672</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00673"></a><span class="lineno"> 673</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,0,0,3> E2 ## E0 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00674"></a><span class="lineno"> 674</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00675"></a><span class="lineno"> 675</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00676"></a><span class="lineno"> 676</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00677"></a><span class="lineno"> 677</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,0,1,3> E2 ## E0 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00678"></a><span class="lineno"> 678</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00679"></a><span class="lineno"> 679</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00680"></a><span class="lineno"> 680</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00681"></a><span class="lineno"> 681</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,0,2,3> E2 ## E0 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00682"></a><span class="lineno"> 682</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,0,3,0> E2 ## E0 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00683"></a><span class="lineno"> 683</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,0,3,1> E2 ## E0 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00684"></a><span class="lineno"> 684</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,0,3,2> E2 ## E0 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00685"></a><span class="lineno"> 685</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,0,3,3> E2 ## E0 ## E3 ## E3; }; \</span></div>
+<div class="line"><a name="l00686"></a><span class="lineno"> 686</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00687"></a><span class="lineno"> 687</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00688"></a><span class="lineno"> 688</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00689"></a><span class="lineno"> 689</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,1,0,3> E2 ## E1 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00690"></a><span class="lineno"> 690</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00691"></a><span class="lineno"> 691</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00692"></a><span class="lineno"> 692</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00693"></a><span class="lineno"> 693</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,1,1,3> E2 ## E1 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00694"></a><span class="lineno"> 694</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00695"></a><span class="lineno"> 695</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00696"></a><span class="lineno"> 696</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00697"></a><span class="lineno"> 697</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,1,2,3> E2 ## E1 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00698"></a><span class="lineno"> 698</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,1,3,0> E2 ## E1 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00699"></a><span class="lineno"> 699</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,1,3,1> E2 ## E1 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00700"></a><span class="lineno"> 700</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,1,3,2> E2 ## E1 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00701"></a><span class="lineno"> 701</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,1,3,3> E2 ## E1 ## E3 ## E3; }; \</span></div>
+<div class="line"><a name="l00702"></a><span class="lineno"> 702</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00703"></a><span class="lineno"> 703</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00704"></a><span class="lineno"> 704</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00705"></a><span class="lineno"> 705</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,2,0,3> E2 ## E2 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00706"></a><span class="lineno"> 706</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00707"></a><span class="lineno"> 707</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00708"></a><span class="lineno"> 708</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00709"></a><span class="lineno"> 709</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,2,1,3> E2 ## E2 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00710"></a><span class="lineno"> 710</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00711"></a><span class="lineno"> 711</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00712"></a><span class="lineno"> 712</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,2,2,2> E2 ## E2 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00713"></a><span class="lineno"> 713</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,2,2,3> E2 ## E2 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00714"></a><span class="lineno"> 714</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,2,3,0> E2 ## E2 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00715"></a><span class="lineno"> 715</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,2,3,1> E2 ## E2 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00716"></a><span class="lineno"> 716</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,2,3,2> E2 ## E2 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00717"></a><span class="lineno"> 717</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,2,3,3> E2 ## E2 ## E3 ## E3; }; \</span></div>
+<div class="line"><a name="l00718"></a><span class="lineno"> 718</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,3,0,0> E2 ## E3 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00719"></a><span class="lineno"> 719</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,3,0,1> E2 ## E3 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00720"></a><span class="lineno"> 720</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,3,0,2> E2 ## E3 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00721"></a><span class="lineno"> 721</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,3,0,3> E2 ## E3 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00722"></a><span class="lineno"> 722</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,3,1,0> E2 ## E3 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00723"></a><span class="lineno"> 723</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,3,1,1> E2 ## E3 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00724"></a><span class="lineno"> 724</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,3,1,2> E2 ## E3 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00725"></a><span class="lineno"> 725</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,3,1,3> E2 ## E3 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00726"></a><span class="lineno"> 726</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,3,2,0> E2 ## E3 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00727"></a><span class="lineno"> 727</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,3,2,1> E2 ## E3 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00728"></a><span class="lineno"> 728</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,3,2,2> E2 ## E3 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00729"></a><span class="lineno"> 729</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,3,2,3> E2 ## E3 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00730"></a><span class="lineno"> 730</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,3,3,0> E2 ## E3 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00731"></a><span class="lineno"> 731</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,3,3,1> E2 ## E3 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00732"></a><span class="lineno"> 732</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,3,3,2> E2 ## E3 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00733"></a><span class="lineno"> 733</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 2,3,3,3> E2 ## E3 ## E3 ## E3; }; \</span></div>
+<div class="line"><a name="l00734"></a><span class="lineno"> 734</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,0,0,0> E3 ## E0 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00735"></a><span class="lineno"> 735</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,0,0,1> E3 ## E0 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00736"></a><span class="lineno"> 736</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,0,0,2> E3 ## E0 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00737"></a><span class="lineno"> 737</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,0,0,3> E3 ## E0 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00738"></a><span class="lineno"> 738</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,0,1,0> E3 ## E0 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00739"></a><span class="lineno"> 739</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,0,1,1> E3 ## E0 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00740"></a><span class="lineno"> 740</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,0,1,2> E3 ## E0 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00741"></a><span class="lineno"> 741</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,0,1,3> E3 ## E0 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00742"></a><span class="lineno"> 742</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,0,2,0> E3 ## E0 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00743"></a><span class="lineno"> 743</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,0,2,1> E3 ## E0 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00744"></a><span class="lineno"> 744</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,0,2,2> E3 ## E0 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00745"></a><span class="lineno"> 745</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,0,2,3> E3 ## E0 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00746"></a><span class="lineno"> 746</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,0,3,0> E3 ## E0 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00747"></a><span class="lineno"> 747</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,0,3,1> E3 ## E0 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00748"></a><span class="lineno"> 748</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,0,3,2> E3 ## E0 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00749"></a><span class="lineno"> 749</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,0,3,3> E3 ## E0 ## E3 ## E3; }; \</span></div>
+<div class="line"><a name="l00750"></a><span class="lineno"> 750</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,1,0,0> E3 ## E1 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00751"></a><span class="lineno"> 751</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,1,0,1> E3 ## E1 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00752"></a><span class="lineno"> 752</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,1,0,2> E3 ## E1 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00753"></a><span class="lineno"> 753</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,1,0,3> E3 ## E1 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00754"></a><span class="lineno"> 754</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,1,1,0> E3 ## E1 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00755"></a><span class="lineno"> 755</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,1,1,1> E3 ## E1 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00756"></a><span class="lineno"> 756</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,1,1,2> E3 ## E1 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00757"></a><span class="lineno"> 757</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,1,1,3> E3 ## E1 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00758"></a><span class="lineno"> 758</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,1,2,0> E3 ## E1 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00759"></a><span class="lineno"> 759</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,1,2,1> E3 ## E1 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00760"></a><span class="lineno"> 760</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,1,2,2> E3 ## E1 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00761"></a><span class="lineno"> 761</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,1,2,3> E3 ## E1 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00762"></a><span class="lineno"> 762</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,1,3,0> E3 ## E1 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00763"></a><span class="lineno"> 763</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,1,3,1> E3 ## E1 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00764"></a><span class="lineno"> 764</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,1,3,2> E3 ## E1 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00765"></a><span class="lineno"> 765</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,1,3,3> E3 ## E1 ## E3 ## E3; }; \</span></div>
+<div class="line"><a name="l00766"></a><span class="lineno"> 766</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,2,0,0> E3 ## E2 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00767"></a><span class="lineno"> 767</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,2,0,1> E3 ## E2 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00768"></a><span class="lineno"> 768</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,2,0,2> E3 ## E2 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00769"></a><span class="lineno"> 769</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,2,0,3> E3 ## E2 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00770"></a><span class="lineno"> 770</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,2,1,0> E3 ## E2 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00771"></a><span class="lineno"> 771</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,2,1,1> E3 ## E2 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00772"></a><span class="lineno"> 772</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,2,1,2> E3 ## E2 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00773"></a><span class="lineno"> 773</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,2,1,3> E3 ## E2 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00774"></a><span class="lineno"> 774</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,2,2,0> E3 ## E2 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00775"></a><span class="lineno"> 775</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,2,2,1> E3 ## E2 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00776"></a><span class="lineno"> 776</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,2,2,2> E3 ## E2 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00777"></a><span class="lineno"> 777</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,2,2,3> E3 ## E2 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00778"></a><span class="lineno"> 778</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,2,3,0> E3 ## E2 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00779"></a><span class="lineno"> 779</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,2,3,1> E3 ## E2 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00780"></a><span class="lineno"> 780</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,2,3,2> E3 ## E2 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00781"></a><span class="lineno"> 781</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,2,3,3> E3 ## E2 ## E3 ## E3; }; \</span></div>
+<div class="line"><a name="l00782"></a><span class="lineno"> 782</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,3,0,0> E3 ## E3 ## E0 ## E0; }; \</span></div>
+<div class="line"><a name="l00783"></a><span class="lineno"> 783</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,3,0,1> E3 ## E3 ## E0 ## E1; }; \</span></div>
+<div class="line"><a name="l00784"></a><span class="lineno"> 784</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,3,0,2> E3 ## E3 ## E0 ## E2; }; \</span></div>
+<div class="line"><a name="l00785"></a><span class="lineno"> 785</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,3,0,3> E3 ## E3 ## E0 ## E3; }; \</span></div>
+<div class="line"><a name="l00786"></a><span class="lineno"> 786</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,3,1,0> E3 ## E3 ## E1 ## E0; }; \</span></div>
+<div class="line"><a name="l00787"></a><span class="lineno"> 787</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,3,1,1> E3 ## E3 ## E1 ## E1; }; \</span></div>
+<div class="line"><a name="l00788"></a><span class="lineno"> 788</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,3,1,2> E3 ## E3 ## E1 ## E2; }; \</span></div>
+<div class="line"><a name="l00789"></a><span class="lineno"> 789</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,3,1,3> E3 ## E3 ## E1 ## E3; }; \</span></div>
+<div class="line"><a name="l00790"></a><span class="lineno"> 790</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,3,2,0> E3 ## E3 ## E2 ## E0; }; \</span></div>
+<div class="line"><a name="l00791"></a><span class="lineno"> 791</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,3,2,1> E3 ## E3 ## E2 ## E1; }; \</span></div>
+<div class="line"><a name="l00792"></a><span class="lineno"> 792</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,3,2,2> E3 ## E3 ## E2 ## E2; }; \</span></div>
+<div class="line"><a name="l00793"></a><span class="lineno"> 793</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,3,2,3> E3 ## E3 ## E2 ## E3; }; \</span></div>
+<div class="line"><a name="l00794"></a><span class="lineno"> 794</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,3,3,0> E3 ## E3 ## E3 ## E0; }; \</span></div>
+<div class="line"><a name="l00795"></a><span class="lineno"> 795</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,3,3,1> E3 ## E3 ## E3 ## E1; }; \</span></div>
+<div class="line"><a name="l00796"></a><span class="lineno"> 796</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,3,3,2> E3 ## E3 ## E3 ## E2; }; \</span></div>
+<div class="line"><a name="l00797"></a><span class="lineno"> 797</span> <span class="preprocessor"> struct { detail::_swizzle<4, T, P, V, 3,3,3,3> E3 ## E3 ## E3 ## E3; };</span></div>
+<div class="ttc" id="a00162_html_ga4b7956eb6e2fbedfc7cf2e46e85c5139"><div class="ttname"><a href="a00162.html#ga4b7956eb6e2fbedfc7cf2e46e85c5139">glm::e</a></div><div class="ttdeci">GLM_FUNC_DECL GLM_CONSTEXPR genType e()</div><div class="ttdoc">Return e constant. </div></div>
+<div class="ttc" id="a00141_html"><div class="ttname"><a href="a00141.html">glm</a></div><div class="ttdef"><b>Definition:</b> <a href="a00003_source.html#l00011">_noise.hpp:11</a></div></div>
+</div><!-- fragment --></div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated by  <a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.10
+</small></address>
+</body>
+</html>
diff --git a/src/third_party/glm/doc/api/a00005.html b/src/third_party/glm/doc/api/a00005.html
new file mode 100644
index 0000000..05e12ab
--- /dev/null
+++ b/src/third_party/glm/doc/api/a00005.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.10"/>
+<title>0.9.8: _swizzle_func.hpp File Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="logo.png"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">0.9.8
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.10 -->
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div id="navrow2" class="tabs2">
+ <ul class="tablist">
+ <li><a href="files.html"><span>File List</span></a></li>
+ </ul>
+ </div>
+<div id="nav-path" class="navpath">
+ <ul>
+<li class="navelem"><a class="el" href="dir_275089585c7fc1b5fd5d7d42c69cb1da.html">D:</a></li><li class="navelem"><a class="el" href="dir_7b98f88bffbed4b390b5f8f520d9c08e.html">Source</a></li><li class="navelem"><a class="el" href="dir_1f76e953200861345293ade84ac7fb6c.html">G-Truc</a></li><li class="navelem"><a class="el" href="dir_e29b03b892e0e25920d021a614d4db9b.html">glm</a></li><li class="navelem"><a class="el" href="dir_5ce58d942b2d0776e17a9a58abc01e04.html">glm</a></li><li class="navelem"><a class="el" href="dir_e529a619cfdec1fa4c331fb042fd332f.html">detail</a></li> </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+ <div class="headertitle">
+<div class="title">_swizzle_func.hpp File Reference</div> </div>
+</div><!--header-->
+<div class="contents">
+
+<p><a href="a00005_source.html">Go to the source code of this file.</a></p>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p><a class="el" href="a00156.html">GLM Core</a> </p>
+
+<p>Definition in file <a class="el" href="a00005_source.html">_swizzle_func.hpp</a>.</p>
+</div></div><!-- contents -->
+<!-- start footer part -->
+<hr class="footer"/><address class="footer"><small>
+Generated by  <a href="http://www.doxygen.org/index.html">
+<img class="footer" src="doxygen.png" alt="doxygen"/>
+</a> 1.8.10
+</small></address>
+</body>
+</html>
diff --git a/src/third_party/glm/doc/api/a00005_source.html b/src/third_party/glm/doc/api/a00005_source.html
new file mode 100644
index 0000000..b8cf723
--- /dev/null
+++ b/src/third_party/glm/doc/api/a00005_source.html
@@ -0,0 +1,754 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen 1.8.10"/>
+<title>0.9.8: _swizzle_func.hpp Source File</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr style="height: 56px;">
+ <td id="projectlogo"><img alt="Logo" src="logo.png"/></td>
+ <td id="projectalign" style="padding-left: 0.5em;">
+ <div id="projectname">0.9.8
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.8.10 -->
+ <div id="navrow1" class="tabs">
+ <ul class="tablist">
+ <li><a href="index.html"><span>Main Page</span></a></li>
+ <li><a href="modules.html"><span>Modules</span></a></li>
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
+ </ul>
+ </div>
+ <div id="navrow2" class="tabs2">
+ <ul class="tablist">
+ <li><a href="files.html"><span>File List</span></a></li>
+ </ul>
+ </div>
+<div id="nav-path" class="navpath">
+ <ul>
+<li class="navelem"><a class="el" href="dir_275089585c7fc1b5fd5d7d42c69cb1da.html">D:</a></li><li class="navelem"><a class="el" href="dir_7b98f88bffbed4b390b5f8f520d9c08e.html">Source</a></li><li class="navelem"><a class="el" href="dir_1f76e953200861345293ade84ac7fb6c.html">G-Truc</a></li><li class="navelem"><a class="el" href="dir_e29b03b892e0e25920d021a614d4db9b.html">glm</a></li><li class="navelem"><a class="el" href="dir_5ce58d942b2d0776e17a9a58abc01e04.html">glm</a></li><li class="navelem"><a class="el" href="dir_e529a619cfdec1fa4c331fb042fd332f.html">detail</a></li> </ul>
+</div>
+</div><!-- top -->
+<div class="header">
+ <div class="headertitle">
+<div class="title">_swizzle_func.hpp</div> </div>
+</div><!--header-->
+<div class="contents">
+<a href="a00005.html">Go to the documentation of this file.</a><div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span> </div>
+<div class="line"><a name="l00004"></a><span class="lineno"> 4</span> <span class="preprocessor">#pragma once</span></div>
+<div class="line"><a name="l00005"></a><span class="lineno"> 5</span> </div>
+<div class="line"><a name="l00006"></a><span class="lineno"> 6</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B) \</span></div>
+<div class="line"><a name="l00007"></a><span class="lineno"> 7</span> <span class="preprocessor"> SWIZZLED_TYPE<TMPL_TYPE, PRECISION> A ## B() CONST \</span></div>
+<div class="line"><a name="l00008"></a><span class="lineno"> 8</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00009"></a><span class="lineno"> 9</span> <span class="preprocessor"> return SWIZZLED_TYPE<TMPL_TYPE, PRECISION>(this->A, this->B); \</span></div>
+<div class="line"><a name="l00010"></a><span class="lineno"> 10</span> <span class="preprocessor"> }</span></div>
+<div class="line"><a name="l00011"></a><span class="lineno"> 11</span> </div>
+<div class="line"><a name="l00012"></a><span class="lineno"> 12</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C) \</span></div>
+<div class="line"><a name="l00013"></a><span class="lineno"> 13</span> <span class="preprocessor"> SWIZZLED_TYPE<TMPL_TYPE, PRECISION> A ## B ## C() CONST \</span></div>
+<div class="line"><a name="l00014"></a><span class="lineno"> 14</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00015"></a><span class="lineno"> 15</span> <span class="preprocessor"> return SWIZZLED_TYPE<TMPL_TYPE, PRECISION>(this->A, this->B, this->C); \</span></div>
+<div class="line"><a name="l00016"></a><span class="lineno"> 16</span> <span class="preprocessor"> }</span></div>
+<div class="line"><a name="l00017"></a><span class="lineno"> 17</span> </div>
+<div class="line"><a name="l00018"></a><span class="lineno"> 18</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C, D) \</span></div>
+<div class="line"><a name="l00019"></a><span class="lineno"> 19</span> <span class="preprocessor"> SWIZZLED_TYPE<TMPL_TYPE, PRECISION> A ## B ## C ## D() CONST \</span></div>
+<div class="line"><a name="l00020"></a><span class="lineno"> 20</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00021"></a><span class="lineno"> 21</span> <span class="preprocessor"> return SWIZZLED_TYPE<TMPL_TYPE, PRECISION>(this->A, this->B, this->C, this->D); \</span></div>
+<div class="line"><a name="l00022"></a><span class="lineno"> 22</span> <span class="preprocessor"> }</span></div>
+<div class="line"><a name="l00023"></a><span class="lineno"> 23</span> </div>
+<div class="line"><a name="l00024"></a><span class="lineno"> 24</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_VEC2_ENTRY_DEF(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B) \</span></div>
+<div class="line"><a name="l00025"></a><span class="lineno"> 25</span> <span class="preprocessor"> template <typename TMPL_TYPE> \</span></div>
+<div class="line"><a name="l00026"></a><span class="lineno"> 26</span> <span class="preprocessor"> SWIZZLED_TYPE<TMPL_TYPE> CLASS_TYPE<TMPL_TYPE, PRECISION>::A ## B() CONST \</span></div>
+<div class="line"><a name="l00027"></a><span class="lineno"> 27</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00028"></a><span class="lineno"> 28</span> <span class="preprocessor"> return SWIZZLED_TYPE<TMPL_TYPE, PRECISION>(this->A, this->B); \</span></div>
+<div class="line"><a name="l00029"></a><span class="lineno"> 29</span> <span class="preprocessor"> }</span></div>
+<div class="line"><a name="l00030"></a><span class="lineno"> 30</span> </div>
+<div class="line"><a name="l00031"></a><span class="lineno"> 31</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_VEC3_ENTRY_DEF(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C) \</span></div>
+<div class="line"><a name="l00032"></a><span class="lineno"> 32</span> <span class="preprocessor"> template <typename TMPL_TYPE> \</span></div>
+<div class="line"><a name="l00033"></a><span class="lineno"> 33</span> <span class="preprocessor"> SWIZZLED_TYPE<TMPL_TYPE> CLASS_TYPE<TMPL_TYPE, PRECISION>::A ## B ## C() CONST \</span></div>
+<div class="line"><a name="l00034"></a><span class="lineno"> 34</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00035"></a><span class="lineno"> 35</span> <span class="preprocessor"> return SWIZZLED_TYPE<TMPL_TYPE, PRECISION>(this->A, this->B, this->C); \</span></div>
+<div class="line"><a name="l00036"></a><span class="lineno"> 36</span> <span class="preprocessor"> }</span></div>
+<div class="line"><a name="l00037"></a><span class="lineno"> 37</span> </div>
+<div class="line"><a name="l00038"></a><span class="lineno"> 38</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_VEC4_ENTRY_DEF(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C, D) \</span></div>
+<div class="line"><a name="l00039"></a><span class="lineno"> 39</span> <span class="preprocessor"> template <typename TMPL_TYPE> \</span></div>
+<div class="line"><a name="l00040"></a><span class="lineno"> 40</span> <span class="preprocessor"> SWIZZLED_TYPE<TMPL_TYPE> CLASS_TYPE<TMPL_TYPE, PRECISION>::A ## B ## C ## D() CONST \</span></div>
+<div class="line"><a name="l00041"></a><span class="lineno"> 41</span> <span class="preprocessor"> { \</span></div>
+<div class="line"><a name="l00042"></a><span class="lineno"> 42</span> <span class="preprocessor"> return SWIZZLED_TYPE<TMPL_TYPE, PRECISION>(this->A, this->B, this->C, this->D); \</span></div>
+<div class="line"><a name="l00043"></a><span class="lineno"> 43</span> <span class="preprocessor"> }</span></div>
+<div class="line"><a name="l00044"></a><span class="lineno"> 44</span> </div>
+<div class="line"><a name="l00045"></a><span class="lineno"> 45</span> <span class="preprocessor">#define GLM_MUTABLE</span></div>
+<div class="line"><a name="l00046"></a><span class="lineno"> 46</span> </div>
+<div class="line"><a name="l00047"></a><span class="lineno"> 47</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B) \</span></div>
+<div class="line"><a name="l00048"></a><span class="lineno"> 48</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B) \</span></div>
+<div class="line"><a name="l00049"></a><span class="lineno"> 49</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A)</span></div>
+<div class="line"><a name="l00050"></a><span class="lineno"> 50</span> </div>
+<div class="line"><a name="l00051"></a><span class="lineno"> 51</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_REF_FROM_VEC2(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE) \</span></div>
+<div class="line"><a name="l00052"></a><span class="lineno"> 52</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, x, y) \</span></div>
+<div class="line"><a name="l00053"></a><span class="lineno"> 53</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, r, g) \</span></div>
+<div class="line"><a name="l00054"></a><span class="lineno"> 54</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, s, t)</span></div>
+<div class="line"><a name="l00055"></a><span class="lineno"> 55</span> </div>
+<div class="line"><a name="l00056"></a><span class="lineno"> 56</span> <span class="comment">//GLM_SWIZZLE_GEN_REF_FROM_VEC2(valType, detail::vec2, detail::ref2)</span></div>
+<div class="line"><a name="l00057"></a><span class="lineno"> 57</span> </div>
+<div class="line"><a name="l00058"></a><span class="lineno"> 58</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_REF2_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \</span></div>
+<div class="line"><a name="l00059"></a><span class="lineno"> 59</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B) \</span></div>
+<div class="line"><a name="l00060"></a><span class="lineno"> 60</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, C) \</span></div>
+<div class="line"><a name="l00061"></a><span class="lineno"> 61</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A) \</span></div>
+<div class="line"><a name="l00062"></a><span class="lineno"> 62</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, C) \</span></div>
+<div class="line"><a name="l00063"></a><span class="lineno"> 63</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, A) \</span></div>
+<div class="line"><a name="l00064"></a><span class="lineno"> 64</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, B)</span></div>
+<div class="line"><a name="l00065"></a><span class="lineno"> 65</span> </div>
+<div class="line"><a name="l00066"></a><span class="lineno"> 66</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_REF3_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \</span></div>
+<div class="line"><a name="l00067"></a><span class="lineno"> 67</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B, C) \</span></div>
+<div class="line"><a name="l00068"></a><span class="lineno"> 68</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, C, B) \</span></div>
+<div class="line"><a name="l00069"></a><span class="lineno"> 69</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A, C) \</span></div>
+<div class="line"><a name="l00070"></a><span class="lineno"> 70</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, C, A) \</span></div>
+<div class="line"><a name="l00071"></a><span class="lineno"> 71</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, A, B) \</span></div>
+<div class="line"><a name="l00072"></a><span class="lineno"> 72</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, B, A)</span></div>
+<div class="line"><a name="l00073"></a><span class="lineno"> 73</span> </div>
+<div class="line"><a name="l00074"></a><span class="lineno"> 74</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, A, B, C) \</span></div>
+<div class="line"><a name="l00075"></a><span class="lineno"> 75</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_REF3_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B, C) \</span></div>
+<div class="line"><a name="l00076"></a><span class="lineno"> 76</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_REF2_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B, C)</span></div>
+<div class="line"><a name="l00077"></a><span class="lineno"> 77</span> </div>
+<div class="line"><a name="l00078"></a><span class="lineno"> 78</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_REF_FROM_VEC3(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE) \</span></div>
+<div class="line"><a name="l00079"></a><span class="lineno"> 79</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, x, y, z) \</span></div>
+<div class="line"><a name="l00080"></a><span class="lineno"> 80</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, r, g, b) \</span></div>
+<div class="line"><a name="l00081"></a><span class="lineno"> 81</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, s, t, p)</span></div>
+<div class="line"><a name="l00082"></a><span class="lineno"> 82</span> </div>
+<div class="line"><a name="l00083"></a><span class="lineno"> 83</span> <span class="comment">//GLM_SWIZZLE_GEN_REF_FROM_VEC3(valType, detail::vec3, detail::ref2, detail::ref3)</span></div>
+<div class="line"><a name="l00084"></a><span class="lineno"> 84</span> </div>
+<div class="line"><a name="l00085"></a><span class="lineno"> 85</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_REF2_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \</span></div>
+<div class="line"><a name="l00086"></a><span class="lineno"> 86</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B) \</span></div>
+<div class="line"><a name="l00087"></a><span class="lineno"> 87</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, C) \</span></div>
+<div class="line"><a name="l00088"></a><span class="lineno"> 88</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, D) \</span></div>
+<div class="line"><a name="l00089"></a><span class="lineno"> 89</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A) \</span></div>
+<div class="line"><a name="l00090"></a><span class="lineno"> 90</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, C) \</span></div>
+<div class="line"><a name="l00091"></a><span class="lineno"> 91</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, D) \</span></div>
+<div class="line"><a name="l00092"></a><span class="lineno"> 92</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, A) \</span></div>
+<div class="line"><a name="l00093"></a><span class="lineno"> 93</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, B) \</span></div>
+<div class="line"><a name="l00094"></a><span class="lineno"> 94</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, D) \</span></div>
+<div class="line"><a name="l00095"></a><span class="lineno"> 95</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, D, A) \</span></div>
+<div class="line"><a name="l00096"></a><span class="lineno"> 96</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, D, B) \</span></div>
+<div class="line"><a name="l00097"></a><span class="lineno"> 97</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, D, C)</span></div>
+<div class="line"><a name="l00098"></a><span class="lineno"> 98</span> </div>
+<div class="line"><a name="l00099"></a><span class="lineno"> 99</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_REF3_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \</span></div>
+<div class="line"><a name="l00100"></a><span class="lineno"> 100</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, B, C) \</span></div>
+<div class="line"><a name="l00101"></a><span class="lineno"> 101</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, B, D) \</span></div>
+<div class="line"><a name="l00102"></a><span class="lineno"> 102</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, C, B) \</span></div>
+<div class="line"><a name="l00103"></a><span class="lineno"> 103</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, C, D) \</span></div>
+<div class="line"><a name="l00104"></a><span class="lineno"> 104</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, D, B) \</span></div>
+<div class="line"><a name="l00105"></a><span class="lineno"> 105</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, D, C) \</span></div>
+<div class="line"><a name="l00106"></a><span class="lineno"> 106</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, A, C) \</span></div>
+<div class="line"><a name="l00107"></a><span class="lineno"> 107</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, A, D) \</span></div>
+<div class="line"><a name="l00108"></a><span class="lineno"> 108</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, C, A) \</span></div>
+<div class="line"><a name="l00109"></a><span class="lineno"> 109</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, C, D) \</span></div>
+<div class="line"><a name="l00110"></a><span class="lineno"> 110</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, D, A) \</span></div>
+<div class="line"><a name="l00111"></a><span class="lineno"> 111</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, D, C) \</span></div>
+<div class="line"><a name="l00112"></a><span class="lineno"> 112</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, A, B) \</span></div>
+<div class="line"><a name="l00113"></a><span class="lineno"> 113</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, A, D) \</span></div>
+<div class="line"><a name="l00114"></a><span class="lineno"> 114</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, B, A) \</span></div>
+<div class="line"><a name="l00115"></a><span class="lineno"> 115</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, B, D) \</span></div>
+<div class="line"><a name="l00116"></a><span class="lineno"> 116</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, D, A) \</span></div>
+<div class="line"><a name="l00117"></a><span class="lineno"> 117</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, D, B) \</span></div>
+<div class="line"><a name="l00118"></a><span class="lineno"> 118</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, A, B) \</span></div>
+<div class="line"><a name="l00119"></a><span class="lineno"> 119</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, A, C) \</span></div>
+<div class="line"><a name="l00120"></a><span class="lineno"> 120</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, B, A) \</span></div>
+<div class="line"><a name="l00121"></a><span class="lineno"> 121</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, B, C) \</span></div>
+<div class="line"><a name="l00122"></a><span class="lineno"> 122</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, C, A) \</span></div>
+<div class="line"><a name="l00123"></a><span class="lineno"> 123</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, C, B)</span></div>
+<div class="line"><a name="l00124"></a><span class="lineno"> 124</span> </div>
+<div class="line"><a name="l00125"></a><span class="lineno"> 125</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_REF4_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \</span></div>
+<div class="line"><a name="l00126"></a><span class="lineno"> 126</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, C, B, D) \</span></div>
+<div class="line"><a name="l00127"></a><span class="lineno"> 127</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, C, D, B) \</span></div>
+<div class="line"><a name="l00128"></a><span class="lineno"> 128</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, D, B, C) \</span></div>
+<div class="line"><a name="l00129"></a><span class="lineno"> 129</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, D, C, B) \</span></div>
+<div class="line"><a name="l00130"></a><span class="lineno"> 130</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, B, D, C) \</span></div>
+<div class="line"><a name="l00131"></a><span class="lineno"> 131</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, B, C, D) \</span></div>
+<div class="line"><a name="l00132"></a><span class="lineno"> 132</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, C, A, D) \</span></div>
+<div class="line"><a name="l00133"></a><span class="lineno"> 133</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, C, D, A) \</span></div>
+<div class="line"><a name="l00134"></a><span class="lineno"> 134</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, D, A, C) \</span></div>
+<div class="line"><a name="l00135"></a><span class="lineno"> 135</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, D, C, A) \</span></div>
+<div class="line"><a name="l00136"></a><span class="lineno"> 136</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, A, D, C) \</span></div>
+<div class="line"><a name="l00137"></a><span class="lineno"> 137</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, A, C, D) \</span></div>
+<div class="line"><a name="l00138"></a><span class="lineno"> 138</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, B, A, D) \</span></div>
+<div class="line"><a name="l00139"></a><span class="lineno"> 139</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, B, D, A) \</span></div>
+<div class="line"><a name="l00140"></a><span class="lineno"> 140</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, D, A, B) \</span></div>
+<div class="line"><a name="l00141"></a><span class="lineno"> 141</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, D, B, A) \</span></div>
+<div class="line"><a name="l00142"></a><span class="lineno"> 142</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, A, D, B) \</span></div>
+<div class="line"><a name="l00143"></a><span class="lineno"> 143</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, A, B, D) \</span></div>
+<div class="line"><a name="l00144"></a><span class="lineno"> 144</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, C, B, A) \</span></div>
+<div class="line"><a name="l00145"></a><span class="lineno"> 145</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, C, A, B) \</span></div>
+<div class="line"><a name="l00146"></a><span class="lineno"> 146</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, A, B, C) \</span></div>
+<div class="line"><a name="l00147"></a><span class="lineno"> 147</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, A, C, B) \</span></div>
+<div class="line"><a name="l00148"></a><span class="lineno"> 148</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, B, A, C) \</span></div>
+<div class="line"><a name="l00149"></a><span class="lineno"> 149</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, B, C, A)</span></div>
+<div class="line"><a name="l00150"></a><span class="lineno"> 150</span> </div>
+<div class="line"><a name="l00151"></a><span class="lineno"> 151</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, A, B, C, D) \</span></div>
+<div class="line"><a name="l00152"></a><span class="lineno"> 152</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_REF2_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B, C, D) \</span></div>
+<div class="line"><a name="l00153"></a><span class="lineno"> 153</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_REF3_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B, C, D) \</span></div>
+<div class="line"><a name="l00154"></a><span class="lineno"> 154</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_REF4_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC4_TYPE, A, B, C, D)</span></div>
+<div class="line"><a name="l00155"></a><span class="lineno"> 155</span> </div>
+<div class="line"><a name="l00156"></a><span class="lineno"> 156</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_REF_FROM_VEC4(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE) \</span></div>
+<div class="line"><a name="l00157"></a><span class="lineno"> 157</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, x, y, z, w) \</span></div>
+<div class="line"><a name="l00158"></a><span class="lineno"> 158</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, r, g, b, a) \</span></div>
+<div class="line"><a name="l00159"></a><span class="lineno"> 159</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t, p, q)</span></div>
+<div class="line"><a name="l00160"></a><span class="lineno"> 160</span> </div>
+<div class="line"><a name="l00161"></a><span class="lineno"> 161</span> <span class="comment">//GLM_SWIZZLE_GEN_REF_FROM_VEC4(valType, detail::vec4, detail::ref2, detail::ref3, detail::ref4)</span></div>
+<div class="line"><a name="l00162"></a><span class="lineno"> 162</span> </div>
+<div class="line"><a name="l00163"></a><span class="lineno"> 163</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B) \</span></div>
+<div class="line"><a name="l00164"></a><span class="lineno"> 164</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A) \</span></div>
+<div class="line"><a name="l00165"></a><span class="lineno"> 165</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B) \</span></div>
+<div class="line"><a name="l00166"></a><span class="lineno"> 166</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A) \</span></div>
+<div class="line"><a name="l00167"></a><span class="lineno"> 167</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B)</span></div>
+<div class="line"><a name="l00168"></a><span class="lineno"> 168</span> </div>
+<div class="line"><a name="l00169"></a><span class="lineno"> 169</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B) \</span></div>
+<div class="line"><a name="l00170"></a><span class="lineno"> 170</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A) \</span></div>
+<div class="line"><a name="l00171"></a><span class="lineno"> 171</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B) \</span></div>
+<div class="line"><a name="l00172"></a><span class="lineno"> 172</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A) \</span></div>
+<div class="line"><a name="l00173"></a><span class="lineno"> 173</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B) \</span></div>
+<div class="line"><a name="l00174"></a><span class="lineno"> 174</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A) \</span></div>
+<div class="line"><a name="l00175"></a><span class="lineno"> 175</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B) \</span></div>
+<div class="line"><a name="l00176"></a><span class="lineno"> 176</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A) \</span></div>
+<div class="line"><a name="l00177"></a><span class="lineno"> 177</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B)</span></div>
+<div class="line"><a name="l00178"></a><span class="lineno"> 178</span> </div>
+<div class="line"><a name="l00179"></a><span class="lineno"> 179</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B) \</span></div>
+<div class="line"><a name="l00180"></a><span class="lineno"> 180</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, A) \</span></div>
+<div class="line"><a name="l00181"></a><span class="lineno"> 181</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, B) \</span></div>
+<div class="line"><a name="l00182"></a><span class="lineno"> 182</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, A) \</span></div>
+<div class="line"><a name="l00183"></a><span class="lineno"> 183</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, B) \</span></div>
+<div class="line"><a name="l00184"></a><span class="lineno"> 184</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, A) \</span></div>
+<div class="line"><a name="l00185"></a><span class="lineno"> 185</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, B) \</span></div>
+<div class="line"><a name="l00186"></a><span class="lineno"> 186</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, A) \</span></div>
+<div class="line"><a name="l00187"></a><span class="lineno"> 187</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, B) \</span></div>
+<div class="line"><a name="l00188"></a><span class="lineno"> 188</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, A) \</span></div>
+<div class="line"><a name="l00189"></a><span class="lineno"> 189</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, B) \</span></div>
+<div class="line"><a name="l00190"></a><span class="lineno"> 190</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, A) \</span></div>
+<div class="line"><a name="l00191"></a><span class="lineno"> 191</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, B) \</span></div>
+<div class="line"><a name="l00192"></a><span class="lineno"> 192</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, A) \</span></div>
+<div class="line"><a name="l00193"></a><span class="lineno"> 193</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, B) \</span></div>
+<div class="line"><a name="l00194"></a><span class="lineno"> 194</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, A) \</span></div>
+<div class="line"><a name="l00195"></a><span class="lineno"> 195</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, B)</span></div>
+<div class="line"><a name="l00196"></a><span class="lineno"> 196</span> </div>
+<div class="line"><a name="l00197"></a><span class="lineno"> 197</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, A, B) \</span></div>
+<div class="line"><a name="l00198"></a><span class="lineno"> 198</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B) \</span></div>
+<div class="line"><a name="l00199"></a><span class="lineno"> 199</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B) \</span></div>
+<div class="line"><a name="l00200"></a><span class="lineno"> 200</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC4_TYPE, A, B)</span></div>
+<div class="line"><a name="l00201"></a><span class="lineno"> 201</span> </div>
+<div class="line"><a name="l00202"></a><span class="lineno"> 202</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_VEC_FROM_VEC2(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE) \</span></div>
+<div class="line"><a name="l00203"></a><span class="lineno"> 203</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, x, y) \</span></div>
+<div class="line"><a name="l00204"></a><span class="lineno"> 204</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, r, g) \</span></div>
+<div class="line"><a name="l00205"></a><span class="lineno"> 205</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t)</span></div>
+<div class="line"><a name="l00206"></a><span class="lineno"> 206</span> </div>
+<div class="line"><a name="l00207"></a><span class="lineno"> 207</span> <span class="comment">//GLM_SWIZZLE_GEN_VEC_FROM_VEC2(valType, detail::vec2, detail::vec2, detail::vec3, detail::vec4)</span></div>
+<div class="line"><a name="l00208"></a><span class="lineno"> 208</span> </div>
+<div class="line"><a name="l00209"></a><span class="lineno"> 209</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \</span></div>
+<div class="line"><a name="l00210"></a><span class="lineno"> 210</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A) \</span></div>
+<div class="line"><a name="l00211"></a><span class="lineno"> 211</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B) \</span></div>
+<div class="line"><a name="l00212"></a><span class="lineno"> 212</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C) \</span></div>
+<div class="line"><a name="l00213"></a><span class="lineno"> 213</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A) \</span></div>
+<div class="line"><a name="l00214"></a><span class="lineno"> 214</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B) \</span></div>
+<div class="line"><a name="l00215"></a><span class="lineno"> 215</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C) \</span></div>
+<div class="line"><a name="l00216"></a><span class="lineno"> 216</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A) \</span></div>
+<div class="line"><a name="l00217"></a><span class="lineno"> 217</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B) \</span></div>
+<div class="line"><a name="l00218"></a><span class="lineno"> 218</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C)</span></div>
+<div class="line"><a name="l00219"></a><span class="lineno"> 219</span> </div>
+<div class="line"><a name="l00220"></a><span class="lineno"> 220</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \</span></div>
+<div class="line"><a name="l00221"></a><span class="lineno"> 221</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A) \</span></div>
+<div class="line"><a name="l00222"></a><span class="lineno"> 222</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B) \</span></div>
+<div class="line"><a name="l00223"></a><span class="lineno"> 223</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C) \</span></div>
+<div class="line"><a name="l00224"></a><span class="lineno"> 224</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A) \</span></div>
+<div class="line"><a name="l00225"></a><span class="lineno"> 225</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B) \</span></div>
+<div class="line"><a name="l00226"></a><span class="lineno"> 226</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C) \</span></div>
+<div class="line"><a name="l00227"></a><span class="lineno"> 227</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A) \</span></div>
+<div class="line"><a name="l00228"></a><span class="lineno"> 228</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B) \</span></div>
+<div class="line"><a name="l00229"></a><span class="lineno"> 229</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C) \</span></div>
+<div class="line"><a name="l00230"></a><span class="lineno"> 230</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A) \</span></div>
+<div class="line"><a name="l00231"></a><span class="lineno"> 231</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B) \</span></div>
+<div class="line"><a name="l00232"></a><span class="lineno"> 232</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C) \</span></div>
+<div class="line"><a name="l00233"></a><span class="lineno"> 233</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A) \</span></div>
+<div class="line"><a name="l00234"></a><span class="lineno"> 234</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B) \</span></div>
+<div class="line"><a name="l00235"></a><span class="lineno"> 235</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C) \</span></div>
+<div class="line"><a name="l00236"></a><span class="lineno"> 236</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A) \</span></div>
+<div class="line"><a name="l00237"></a><span class="lineno"> 237</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B) \</span></div>
+<div class="line"><a name="l00238"></a><span class="lineno"> 238</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C) \</span></div>
+<div class="line"><a name="l00239"></a><span class="lineno"> 239</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A) \</span></div>
+<div class="line"><a name="l00240"></a><span class="lineno"> 240</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B) \</span></div>
+<div class="line"><a name="l00241"></a><span class="lineno"> 241</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C) \</span></div>
+<div class="line"><a name="l00242"></a><span class="lineno"> 242</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A) \</span></div>
+<div class="line"><a name="l00243"></a><span class="lineno"> 243</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B) \</span></div>
+<div class="line"><a name="l00244"></a><span class="lineno"> 244</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C) \</span></div>
+<div class="line"><a name="l00245"></a><span class="lineno"> 245</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A) \</span></div>
+<div class="line"><a name="l00246"></a><span class="lineno"> 246</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B) \</span></div>
+<div class="line"><a name="l00247"></a><span class="lineno"> 247</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C)</span></div>
+<div class="line"><a name="l00248"></a><span class="lineno"> 248</span> </div>
+<div class="line"><a name="l00249"></a><span class="lineno"> 249</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \</span></div>
+<div class="line"><a name="l00250"></a><span class="lineno"> 250</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, A) \</span></div>
+<div class="line"><a name="l00251"></a><span class="lineno"> 251</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, B) \</span></div>
+<div class="line"><a name="l00252"></a><span class="lineno"> 252</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, C) \</span></div>
+<div class="line"><a name="l00253"></a><span class="lineno"> 253</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, A) \</span></div>
+<div class="line"><a name="l00254"></a><span class="lineno"> 254</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, B) \</span></div>
+<div class="line"><a name="l00255"></a><span class="lineno"> 255</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, C) \</span></div>
+<div class="line"><a name="l00256"></a><span class="lineno"> 256</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, A) \</span></div>
+<div class="line"><a name="l00257"></a><span class="lineno"> 257</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, B) \</span></div>
+<div class="line"><a name="l00258"></a><span class="lineno"> 258</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, C) \</span></div>
+<div class="line"><a name="l00259"></a><span class="lineno"> 259</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, A) \</span></div>
+<div class="line"><a name="l00260"></a><span class="lineno"> 260</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, B) \</span></div>
+<div class="line"><a name="l00261"></a><span class="lineno"> 261</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, C) \</span></div>
+<div class="line"><a name="l00262"></a><span class="lineno"> 262</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, A) \</span></div>
+<div class="line"><a name="l00263"></a><span class="lineno"> 263</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, B) \</span></div>
+<div class="line"><a name="l00264"></a><span class="lineno"> 264</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, C) \</span></div>
+<div class="line"><a name="l00265"></a><span class="lineno"> 265</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, A) \</span></div>
+<div class="line"><a name="l00266"></a><span class="lineno"> 266</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, B) \</span></div>
+<div class="line"><a name="l00267"></a><span class="lineno"> 267</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, C) \</span></div>
+<div class="line"><a name="l00268"></a><span class="lineno"> 268</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, A) \</span></div>
+<div class="line"><a name="l00269"></a><span class="lineno"> 269</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, B) \</span></div>
+<div class="line"><a name="l00270"></a><span class="lineno"> 270</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, C) \</span></div>
+<div class="line"><a name="l00271"></a><span class="lineno"> 271</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, A) \</span></div>
+<div class="line"><a name="l00272"></a><span class="lineno"> 272</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, B) \</span></div>
+<div class="line"><a name="l00273"></a><span class="lineno"> 273</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, C) \</span></div>
+<div class="line"><a name="l00274"></a><span class="lineno"> 274</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, A) \</span></div>
+<div class="line"><a name="l00275"></a><span class="lineno"> 275</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, B) \</span></div>
+<div class="line"><a name="l00276"></a><span class="lineno"> 276</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, C) \</span></div>
+<div class="line"><a name="l00277"></a><span class="lineno"> 277</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, A) \</span></div>
+<div class="line"><a name="l00278"></a><span class="lineno"> 278</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, B) \</span></div>
+<div class="line"><a name="l00279"></a><span class="lineno"> 279</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, C) \</span></div>
+<div class="line"><a name="l00280"></a><span class="lineno"> 280</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, A) \</span></div>
+<div class="line"><a name="l00281"></a><span class="lineno"> 281</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, B) \</span></div>
+<div class="line"><a name="l00282"></a><span class="lineno"> 282</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, C) \</span></div>
+<div class="line"><a name="l00283"></a><span class="lineno"> 283</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, A) \</span></div>
+<div class="line"><a name="l00284"></a><span class="lineno"> 284</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, B) \</span></div>
+<div class="line"><a name="l00285"></a><span class="lineno"> 285</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, C) \</span></div>
+<div class="line"><a name="l00286"></a><span class="lineno"> 286</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, A) \</span></div>
+<div class="line"><a name="l00287"></a><span class="lineno"> 287</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, B) \</span></div>
+<div class="line"><a name="l00288"></a><span class="lineno"> 288</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, C) \</span></div>
+<div class="line"><a name="l00289"></a><span class="lineno"> 289</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, A) \</span></div>
+<div class="line"><a name="l00290"></a><span class="lineno"> 290</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, B) \</span></div>
+<div class="line"><a name="l00291"></a><span class="lineno"> 291</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, C) \</span></div>
+<div class="line"><a name="l00292"></a><span class="lineno"> 292</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, A) \</span></div>
+<div class="line"><a name="l00293"></a><span class="lineno"> 293</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, B) \</span></div>
+<div class="line"><a name="l00294"></a><span class="lineno"> 294</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, C) \</span></div>
+<div class="line"><a name="l00295"></a><span class="lineno"> 295</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, A) \</span></div>
+<div class="line"><a name="l00296"></a><span class="lineno"> 296</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, B) \</span></div>
+<div class="line"><a name="l00297"></a><span class="lineno"> 297</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, C) \</span></div>
+<div class="line"><a name="l00298"></a><span class="lineno"> 298</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, A) \</span></div>
+<div class="line"><a name="l00299"></a><span class="lineno"> 299</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, B) \</span></div>
+<div class="line"><a name="l00300"></a><span class="lineno"> 300</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, C) \</span></div>
+<div class="line"><a name="l00301"></a><span class="lineno"> 301</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, A) \</span></div>
+<div class="line"><a name="l00302"></a><span class="lineno"> 302</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, B) \</span></div>
+<div class="line"><a name="l00303"></a><span class="lineno"> 303</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, C) \</span></div>
+<div class="line"><a name="l00304"></a><span class="lineno"> 304</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, A) \</span></div>
+<div class="line"><a name="l00305"></a><span class="lineno"> 305</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, B) \</span></div>
+<div class="line"><a name="l00306"></a><span class="lineno"> 306</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, C) \</span></div>
+<div class="line"><a name="l00307"></a><span class="lineno"> 307</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, A) \</span></div>
+<div class="line"><a name="l00308"></a><span class="lineno"> 308</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, B) \</span></div>
+<div class="line"><a name="l00309"></a><span class="lineno"> 309</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, C) \</span></div>
+<div class="line"><a name="l00310"></a><span class="lineno"> 310</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, A) \</span></div>
+<div class="line"><a name="l00311"></a><span class="lineno"> 311</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, B) \</span></div>
+<div class="line"><a name="l00312"></a><span class="lineno"> 312</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, C) \</span></div>
+<div class="line"><a name="l00313"></a><span class="lineno"> 313</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, A) \</span></div>
+<div class="line"><a name="l00314"></a><span class="lineno"> 314</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, B) \</span></div>
+<div class="line"><a name="l00315"></a><span class="lineno"> 315</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, C) \</span></div>
+<div class="line"><a name="l00316"></a><span class="lineno"> 316</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, A) \</span></div>
+<div class="line"><a name="l00317"></a><span class="lineno"> 317</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, B) \</span></div>
+<div class="line"><a name="l00318"></a><span class="lineno"> 318</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, C) \</span></div>
+<div class="line"><a name="l00319"></a><span class="lineno"> 319</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, A) \</span></div>
+<div class="line"><a name="l00320"></a><span class="lineno"> 320</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, B) \</span></div>
+<div class="line"><a name="l00321"></a><span class="lineno"> 321</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, C) \</span></div>
+<div class="line"><a name="l00322"></a><span class="lineno"> 322</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, A) \</span></div>
+<div class="line"><a name="l00323"></a><span class="lineno"> 323</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, B) \</span></div>
+<div class="line"><a name="l00324"></a><span class="lineno"> 324</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, C) \</span></div>
+<div class="line"><a name="l00325"></a><span class="lineno"> 325</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, A) \</span></div>
+<div class="line"><a name="l00326"></a><span class="lineno"> 326</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, B) \</span></div>
+<div class="line"><a name="l00327"></a><span class="lineno"> 327</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, C) \</span></div>
+<div class="line"><a name="l00328"></a><span class="lineno"> 328</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, A) \</span></div>
+<div class="line"><a name="l00329"></a><span class="lineno"> 329</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, B) \</span></div>
+<div class="line"><a name="l00330"></a><span class="lineno"> 330</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, C)</span></div>
+<div class="line"><a name="l00331"></a><span class="lineno"> 331</span> </div>
+<div class="line"><a name="l00332"></a><span class="lineno"> 332</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, A, B, C) \</span></div>
+<div class="line"><a name="l00333"></a><span class="lineno"> 333</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B, C) \</span></div>
+<div class="line"><a name="l00334"></a><span class="lineno"> 334</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B, C) \</span></div>
+<div class="line"><a name="l00335"></a><span class="lineno"> 335</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC4_TYPE, A, B, C)</span></div>
+<div class="line"><a name="l00336"></a><span class="lineno"> 336</span> </div>
+<div class="line"><a name="l00337"></a><span class="lineno"> 337</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_VEC_FROM_VEC3(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE) \</span></div>
+<div class="line"><a name="l00338"></a><span class="lineno"> 338</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, x, y, z) \</span></div>
+<div class="line"><a name="l00339"></a><span class="lineno"> 339</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, r, g, b) \</span></div>
+<div class="line"><a name="l00340"></a><span class="lineno"> 340</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t, p)</span></div>
+<div class="line"><a name="l00341"></a><span class="lineno"> 341</span> </div>
+<div class="line"><a name="l00342"></a><span class="lineno"> 342</span> <span class="comment">//GLM_SWIZZLE_GEN_VEC_FROM_VEC3(valType, detail::vec3, detail::vec2, detail::vec3, detail::vec4)</span></div>
+<div class="line"><a name="l00343"></a><span class="lineno"> 343</span> </div>
+<div class="line"><a name="l00344"></a><span class="lineno"> 344</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \</span></div>
+<div class="line"><a name="l00345"></a><span class="lineno"> 345</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A) \</span></div>
+<div class="line"><a name="l00346"></a><span class="lineno"> 346</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B) \</span></div>
+<div class="line"><a name="l00347"></a><span class="lineno"> 347</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C) \</span></div>
+<div class="line"><a name="l00348"></a><span class="lineno"> 348</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D) \</span></div>
+<div class="line"><a name="l00349"></a><span class="lineno"> 349</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A) \</span></div>
+<div class="line"><a name="l00350"></a><span class="lineno"> 350</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B) \</span></div>
+<div class="line"><a name="l00351"></a><span class="lineno"> 351</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C) \</span></div>
+<div class="line"><a name="l00352"></a><span class="lineno"> 352</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D) \</span></div>
+<div class="line"><a name="l00353"></a><span class="lineno"> 353</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A) \</span></div>
+<div class="line"><a name="l00354"></a><span class="lineno"> 354</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B) \</span></div>
+<div class="line"><a name="l00355"></a><span class="lineno"> 355</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C) \</span></div>
+<div class="line"><a name="l00356"></a><span class="lineno"> 356</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D) \</span></div>
+<div class="line"><a name="l00357"></a><span class="lineno"> 357</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A) \</span></div>
+<div class="line"><a name="l00358"></a><span class="lineno"> 358</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B) \</span></div>
+<div class="line"><a name="l00359"></a><span class="lineno"> 359</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C) \</span></div>
+<div class="line"><a name="l00360"></a><span class="lineno"> 360</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D)</span></div>
+<div class="line"><a name="l00361"></a><span class="lineno"> 361</span> </div>
+<div class="line"><a name="l00362"></a><span class="lineno"> 362</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \</span></div>
+<div class="line"><a name="l00363"></a><span class="lineno"> 363</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A) \</span></div>
+<div class="line"><a name="l00364"></a><span class="lineno"> 364</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B) \</span></div>
+<div class="line"><a name="l00365"></a><span class="lineno"> 365</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C) \</span></div>
+<div class="line"><a name="l00366"></a><span class="lineno"> 366</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D) \</span></div>
+<div class="line"><a name="l00367"></a><span class="lineno"> 367</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A) \</span></div>
+<div class="line"><a name="l00368"></a><span class="lineno"> 368</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B) \</span></div>
+<div class="line"><a name="l00369"></a><span class="lineno"> 369</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C) \</span></div>
+<div class="line"><a name="l00370"></a><span class="lineno"> 370</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D) \</span></div>
+<div class="line"><a name="l00371"></a><span class="lineno"> 371</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A) \</span></div>
+<div class="line"><a name="l00372"></a><span class="lineno"> 372</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B) \</span></div>
+<div class="line"><a name="l00373"></a><span class="lineno"> 373</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C) \</span></div>
+<div class="line"><a name="l00374"></a><span class="lineno"> 374</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D) \</span></div>
+<div class="line"><a name="l00375"></a><span class="lineno"> 375</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A) \</span></div>
+<div class="line"><a name="l00376"></a><span class="lineno"> 376</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B) \</span></div>
+<div class="line"><a name="l00377"></a><span class="lineno"> 377</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C) \</span></div>
+<div class="line"><a name="l00378"></a><span class="lineno"> 378</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D) \</span></div>
+<div class="line"><a name="l00379"></a><span class="lineno"> 379</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A) \</span></div>
+<div class="line"><a name="l00380"></a><span class="lineno"> 380</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B) \</span></div>
+<div class="line"><a name="l00381"></a><span class="lineno"> 381</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C) \</span></div>
+<div class="line"><a name="l00382"></a><span class="lineno"> 382</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D) \</span></div>
+<div class="line"><a name="l00383"></a><span class="lineno"> 383</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A) \</span></div>
+<div class="line"><a name="l00384"></a><span class="lineno"> 384</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B) \</span></div>
+<div class="line"><a name="l00385"></a><span class="lineno"> 385</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C) \</span></div>
+<div class="line"><a name="l00386"></a><span class="lineno"> 386</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D) \</span></div>
+<div class="line"><a name="l00387"></a><span class="lineno"> 387</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A) \</span></div>
+<div class="line"><a name="l00388"></a><span class="lineno"> 388</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B) \</span></div>
+<div class="line"><a name="l00389"></a><span class="lineno"> 389</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C) \</span></div>
+<div class="line"><a name="l00390"></a><span class="lineno"> 390</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D) \</span></div>
+<div class="line"><a name="l00391"></a><span class="lineno"> 391</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A) \</span></div>
+<div class="line"><a name="l00392"></a><span class="lineno"> 392</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B) \</span></div>
+<div class="line"><a name="l00393"></a><span class="lineno"> 393</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C) \</span></div>
+<div class="line"><a name="l00394"></a><span class="lineno"> 394</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D) \</span></div>
+<div class="line"><a name="l00395"></a><span class="lineno"> 395</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A) \</span></div>
+<div class="line"><a name="l00396"></a><span class="lineno"> 396</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B) \</span></div>
+<div class="line"><a name="l00397"></a><span class="lineno"> 397</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C) \</span></div>
+<div class="line"><a name="l00398"></a><span class="lineno"> 398</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D) \</span></div>
+<div class="line"><a name="l00399"></a><span class="lineno"> 399</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A) \</span></div>
+<div class="line"><a name="l00400"></a><span class="lineno"> 400</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B) \</span></div>
+<div class="line"><a name="l00401"></a><span class="lineno"> 401</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C) \</span></div>
+<div class="line"><a name="l00402"></a><span class="lineno"> 402</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D) \</span></div>
+<div class="line"><a name="l00403"></a><span class="lineno"> 403</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A) \</span></div>
+<div class="line"><a name="l00404"></a><span class="lineno"> 404</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B) \</span></div>
+<div class="line"><a name="l00405"></a><span class="lineno"> 405</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C) \</span></div>
+<div class="line"><a name="l00406"></a><span class="lineno"> 406</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D) \</span></div>
+<div class="line"><a name="l00407"></a><span class="lineno"> 407</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A) \</span></div>
+<div class="line"><a name="l00408"></a><span class="lineno"> 408</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B) \</span></div>
+<div class="line"><a name="l00409"></a><span class="lineno"> 409</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C) \</span></div>
+<div class="line"><a name="l00410"></a><span class="lineno"> 410</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D) \</span></div>
+<div class="line"><a name="l00411"></a><span class="lineno"> 411</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A) \</span></div>
+<div class="line"><a name="l00412"></a><span class="lineno"> 412</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B) \</span></div>
+<div class="line"><a name="l00413"></a><span class="lineno"> 413</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C) \</span></div>
+<div class="line"><a name="l00414"></a><span class="lineno"> 414</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D) \</span></div>
+<div class="line"><a name="l00415"></a><span class="lineno"> 415</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A) \</span></div>
+<div class="line"><a name="l00416"></a><span class="lineno"> 416</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B) \</span></div>
+<div class="line"><a name="l00417"></a><span class="lineno"> 417</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C) \</span></div>
+<div class="line"><a name="l00418"></a><span class="lineno"> 418</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D) \</span></div>
+<div class="line"><a name="l00419"></a><span class="lineno"> 419</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A) \</span></div>
+<div class="line"><a name="l00420"></a><span class="lineno"> 420</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B) \</span></div>
+<div class="line"><a name="l00421"></a><span class="lineno"> 421</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C) \</span></div>
+<div class="line"><a name="l00422"></a><span class="lineno"> 422</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D) \</span></div>
+<div class="line"><a name="l00423"></a><span class="lineno"> 423</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A) \</span></div>
+<div class="line"><a name="l00424"></a><span class="lineno"> 424</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B) \</span></div>
+<div class="line"><a name="l00425"></a><span class="lineno"> 425</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C) \</span></div>
+<div class="line"><a name="l00426"></a><span class="lineno"> 426</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D)</span></div>
+<div class="line"><a name="l00427"></a><span class="lineno"> 427</span> </div>
+<div class="line"><a name="l00428"></a><span class="lineno"> 428</span> <span class="preprocessor">#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \</span></div>
+<div class="line"><a name="l00429"></a><span class="lineno"> 429</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, A) \</span></div>
+<div class="line"><a name="l00430"></a><span class="lineno"> 430</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, B) \</span></div>
+<div class="line"><a name="l00431"></a><span class="lineno"> 431</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, C) \</span></div>
+<div class="line"><a name="l00432"></a><span class="lineno"> 432</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, D) \</span></div>
+<div class="line"><a name="l00433"></a><span class="lineno"> 433</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, A) \</span></div>
+<div class="line"><a name="l00434"></a><span class="lineno"> 434</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, B) \</span></div>
+<div class="line"><a name="l00435"></a><span class="lineno"> 435</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, C) \</span></div>
+<div class="line"><a name="l00436"></a><span class="lineno"> 436</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, D) \</span></div>
+<div class="line"><a name="l00437"></a><span class="lineno"> 437</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, A) \</span></div>
+<div class="line"><a name="l00438"></a><span class="lineno"> 438</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, B) \</span></div>
+<div class="line"><a name="l00439"></a><span class="lineno"> 439</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, C) \</span></div>
+<div class="line"><a name="l00440"></a><span class="lineno"> 440</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, D) \</span></div>
+<div class="line"><a name="l00441"></a><span class="lineno"> 441</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, A) \</span></div>
+<div class="line"><a name="l00442"></a><span class="lineno"> 442</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, B) \</span></div>
+<div class="line"><a name="l00443"></a><span class="lineno"> 443</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, C) \</span></div>
+<div class="line"><a name="l00444"></a><span class="lineno"> 444</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, D) \</span></div>
+<div class="line"><a name="l00445"></a><span class="lineno"> 445</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, A) \</span></div>
+<div class="line"><a name="l00446"></a><span class="lineno"> 446</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, B) \</span></div>
+<div class="line"><a name="l00447"></a><span class="lineno"> 447</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, C) \</span></div>
+<div class="line"><a name="l00448"></a><span class="lineno"> 448</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, D) \</span></div>
+<div class="line"><a name="l00449"></a><span class="lineno"> 449</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, A) \</span></div>
+<div class="line"><a name="l00450"></a><span class="lineno"> 450</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, B) \</span></div>
+<div class="line"><a name="l00451"></a><span class="lineno"> 451</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, C) \</span></div>
+<div class="line"><a name="l00452"></a><span class="lineno"> 452</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, D) \</span></div>
+<div class="line"><a name="l00453"></a><span class="lineno"> 453</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, A) \</span></div>
+<div class="line"><a name="l00454"></a><span class="lineno"> 454</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, B) \</span></div>
+<div class="line"><a name="l00455"></a><span class="lineno"> 455</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, C) \</span></div>
+<div class="line"><a name="l00456"></a><span class="lineno"> 456</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, D) \</span></div>
+<div class="line"><a name="l00457"></a><span class="lineno"> 457</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, A) \</span></div>
+<div class="line"><a name="l00458"></a><span class="lineno"> 458</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, B) \</span></div>
+<div class="line"><a name="l00459"></a><span class="lineno"> 459</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, C) \</span></div>
+<div class="line"><a name="l00460"></a><span class="lineno"> 460</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, D) \</span></div>
+<div class="line"><a name="l00461"></a><span class="lineno"> 461</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, A) \</span></div>
+<div class="line"><a name="l00462"></a><span class="lineno"> 462</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, B) \</span></div>
+<div class="line"><a name="l00463"></a><span class="lineno"> 463</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, C) \</span></div>
+<div class="line"><a name="l00464"></a><span class="lineno"> 464</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, D) \</span></div>
+<div class="line"><a name="l00465"></a><span class="lineno"> 465</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, A) \</span></div>
+<div class="line"><a name="l00466"></a><span class="lineno"> 466</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, B) \</span></div>
+<div class="line"><a name="l00467"></a><span class="lineno"> 467</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, C) \</span></div>
+<div class="line"><a name="l00468"></a><span class="lineno"> 468</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, D) \</span></div>
+<div class="line"><a name="l00469"></a><span class="lineno"> 469</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, A) \</span></div>
+<div class="line"><a name="l00470"></a><span class="lineno"> 470</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, B) \</span></div>
+<div class="line"><a name="l00471"></a><span class="lineno"> 471</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, C) \</span></div>
+<div class="line"><a name="l00472"></a><span class="lineno"> 472</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, D) \</span></div>
+<div class="line"><a name="l00473"></a><span class="lineno"> 473</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, A) \</span></div>
+<div class="line"><a name="l00474"></a><span class="lineno"> 474</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, B) \</span></div>
+<div class="line"><a name="l00475"></a><span class="lineno"> 475</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, C) \</span></div>
+<div class="line"><a name="l00476"></a><span class="lineno"> 476</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, D) \</span></div>
+<div class="line"><a name="l00477"></a><span class="lineno"> 477</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, A) \</span></div>
+<div class="line"><a name="l00478"></a><span class="lineno"> 478</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, B) \</span></div>
+<div class="line"><a name="l00479"></a><span class="lineno"> 479</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, C) \</span></div>
+<div class="line"><a name="l00480"></a><span class="lineno"> 480</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, D) \</span></div>
+<div class="line"><a name="l00481"></a><span class="lineno"> 481</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, A) \</span></div>
+<div class="line"><a name="l00482"></a><span class="lineno"> 482</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, B) \</span></div>
+<div class="line"><a name="l00483"></a><span class="lineno"> 483</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, C) \</span></div>
+<div class="line"><a name="l00484"></a><span class="lineno"> 484</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, D) \</span></div>
+<div class="line"><a name="l00485"></a><span class="lineno"> 485</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, A) \</span></div>
+<div class="line"><a name="l00486"></a><span class="lineno"> 486</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, B) \</span></div>
+<div class="line"><a name="l00487"></a><span class="lineno"> 487</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, C) \</span></div>
+<div class="line"><a name="l00488"></a><span class="lineno"> 488</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, D) \</span></div>
+<div class="line"><a name="l00489"></a><span class="lineno"> 489</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, A) \</span></div>
+<div class="line"><a name="l00490"></a><span class="lineno"> 490</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, B) \</span></div>
+<div class="line"><a name="l00491"></a><span class="lineno"> 491</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, C) \</span></div>
+<div class="line"><a name="l00492"></a><span class="lineno"> 492</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, D) \</span></div>
+<div class="line"><a name="l00493"></a><span class="lineno"> 493</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, A) \</span></div>
+<div class="line"><a name="l00494"></a><span class="lineno"> 494</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, B) \</span></div>
+<div class="line"><a name="l00495"></a><span class="lineno"> 495</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, C) \</span></div>
+<div class="line"><a name="l00496"></a><span class="lineno"> 496</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, D) \</span></div>
+<div class="line"><a name="l00497"></a><span class="lineno"> 497</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, A) \</span></div>
+<div class="line"><a name="l00498"></a><span class="lineno"> 498</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, B) \</span></div>
+<div class="line"><a name="l00499"></a><span class="lineno"> 499</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, C) \</span></div>
+<div class="line"><a name="l00500"></a><span class="lineno"> 500</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, D) \</span></div>
+<div class="line"><a name="l00501"></a><span class="lineno"> 501</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, A) \</span></div>
+<div class="line"><a name="l00502"></a><span class="lineno"> 502</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, B) \</span></div>
+<div class="line"><a name="l00503"></a><span class="lineno"> 503</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, C) \</span></div>
+<div class="line"><a name="l00504"></a><span class="lineno"> 504</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, D) \</span></div>
+<div class="line"><a name="l00505"></a><span class="lineno"> 505</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, A) \</span></div>
+<div class="line"><a name="l00506"></a><span class="lineno"> 506</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, B) \</span></div>
+<div class="line"><a name="l00507"></a><span class="lineno"> 507</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, C) \</span></div>
+<div class="line"><a name="l00508"></a><span class="lineno"> 508</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, D) \</span></div>
+<div class="line"><a name="l00509"></a><span class="lineno"> 509</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, A) \</span></div>
+<div class="line"><a name="l00510"></a><span class="lineno"> 510</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, B) \</span></div>
+<div class="line"><a name="l00511"></a><span class="lineno"> 511</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, C) \</span></div>
+<div class="line"><a name="l00512"></a><span class="lineno"> 512</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, D) \</span></div>
+<div class="line"><a name="l00513"></a><span class="lineno"> 513</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, A) \</span></div>
+<div class="line"><a name="l00514"></a><span class="lineno"> 514</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, B) \</span></div>
+<div class="line"><a name="l00515"></a><span class="lineno"> 515</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, C) \</span></div>
+<div class="line"><a name="l00516"></a><span class="lineno"> 516</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, D) \</span></div>
+<div class="line"><a name="l00517"></a><span class="lineno"> 517</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, A) \</span></div>
+<div class="line"><a name="l00518"></a><span class="lineno"> 518</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, B) \</span></div>
+<div class="line"><a name="l00519"></a><span class="lineno"> 519</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, C) \</span></div>
+<div class="line"><a name="l00520"></a><span class="lineno"> 520</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, D) \</span></div>
+<div class="line"><a name="l00521"></a><span class="lineno"> 521</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, A) \</span></div>
+<div class="line"><a name="l00522"></a><span class="lineno"> 522</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, B) \</span></div>
+<div class="line"><a name="l00523"></a><span class="lineno"> 523</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, C) \</span></div>
+<div class="line"><a name="l00524"></a><span class="lineno"> 524</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, D) \</span></div>
+<div class="line"><a name="l00525"></a><span class="lineno"> 525</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, A) \</span></div>
+<div class="line"><a name="l00526"></a><span class="lineno"> 526</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, B) \</span></div>
+<div class="line"><a name="l00527"></a><span class="lineno"> 527</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, C) \</span></div>
+<div class="line"><a name="l00528"></a><span class="lineno"> 528</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, D) \</span></div>
+<div class="line"><a name="l00529"></a><span class="lineno"> 529</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, A) \</span></div>
+<div class="line"><a name="l00530"></a><span class="lineno"> 530</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, B) \</span></div>
+<div class="line"><a name="l00531"></a><span class="lineno"> 531</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, C) \</span></div>
+<div class="line"><a name="l00532"></a><span class="lineno"> 532</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, D) \</span></div>
+<div class="line"><a name="l00533"></a><span class="lineno"> 533</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, A) \</span></div>
+<div class="line"><a name="l00534"></a><span class="lineno"> 534</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, B) \</span></div>
+<div class="line"><a name="l00535"></a><span class="lineno"> 535</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, C) \</span></div>
+<div class="line"><a name="l00536"></a><span class="lineno"> 536</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, D) \</span></div>
+<div class="line"><a name="l00537"></a><span class="lineno"> 537</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, A) \</span></div>
+<div class="line"><a name="l00538"></a><span class="lineno"> 538</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, B) \</span></div>
+<div class="line"><a name="l00539"></a><span class="lineno"> 539</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, C) \</span></div>
+<div class="line"><a name="l00540"></a><span class="lineno"> 540</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, D) \</span></div>
+<div class="line"><a name="l00541"></a><span class="lineno"> 541</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, A) \</span></div>
+<div class="line"><a name="l00542"></a><span class="lineno"> 542</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, B) \</span></div>
+<div class="line"><a name="l00543"></a><span class="lineno"> 543</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, C) \</span></div>
+<div class="line"><a name="l00544"></a><span class="lineno"> 544</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, D) \</span></div>
+<div class="line"><a name="l00545"></a><span class="lineno"> 545</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, A) \</span></div>
+<div class="line"><a name="l00546"></a><span class="lineno"> 546</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, B) \</span></div>
+<div class="line"><a name="l00547"></a><span class="lineno"> 547</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, C) \</span></div>
+<div class="line"><a name="l00548"></a><span class="lineno"> 548</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, D) \</span></div>
+<div class="line"><a name="l00549"></a><span class="lineno"> 549</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, A) \</span></div>
+<div class="line"><a name="l00550"></a><span class="lineno"> 550</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, B) \</span></div>
+<div class="line"><a name="l00551"></a><span class="lineno"> 551</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, C) \</span></div>
+<div class="line"><a name="l00552"></a><span class="lineno"> 552</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, D) \</span></div>
+<div class="line"><a name="l00553"></a><span class="lineno"> 553</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, A) \</span></div>
+<div class="line"><a name="l00554"></a><span class="lineno"> 554</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, B) \</span></div>
+<div class="line"><a name="l00555"></a><span class="lineno"> 555</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, C) \</span></div>
+<div class="line"><a name="l00556"></a><span class="lineno"> 556</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, D) \</span></div>
+<div class="line"><a name="l00557"></a><span class="lineno"> 557</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, A) \</span></div>
+<div class="line"><a name="l00558"></a><span class="lineno"> 558</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, B) \</span></div>
+<div class="line"><a name="l00559"></a><span class="lineno"> 559</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, C) \</span></div>
+<div class="line"><a name="l00560"></a><span class="lineno"> 560</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, D) \</span></div>
+<div class="line"><a name="l00561"></a><span class="lineno"> 561</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, A) \</span></div>
+<div class="line"><a name="l00562"></a><span class="lineno"> 562</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, B) \</span></div>
+<div class="line"><a name="l00563"></a><span class="lineno"> 563</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, C) \</span></div>
+<div class="line"><a name="l00564"></a><span class="lineno"> 564</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, D) \</span></div>
+<div class="line"><a name="l00565"></a><span class="lineno"> 565</span> <span class="preprocessor"> GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, A) \</span></div>
+<div class="line"><a name="l00566"><